safeCast lets you cast an object to a known subtype in OCL when the object's runtime type may vary; use it when you need subtype-specific members without assuming that every object has that subtype.
What safeCast does
safeCast attempts to convert an object reference to a target class. If the object is an instance of the target class, the result is that object typed as the target class. If it is not an instance of the target class, the result is null.
This is useful in models with inheritance. For example, an Address reference can point to a USAddress. Only USAddress has the state property, so you must cast the reference before using that property.
Syntax
objectExpression.safeCast(TargetType)
| Part | Meaning |
|---|---|
objectExpression
|
The object reference or expression to cast. |
TargetType
|
The class that you expect the object to be an instance of. |
The target type is normally a subtype of the expression's declared type.
Cast an inherited reference
Assume that Person.address is declared as Address, and USAddress inherits from Address and adds state.
context Person
self.address.safeCast(USAddress).state
If self.address is a USAddress, the cast result is typed as USAddress, so state is available. If it is another kind of Address, safeCast(USAddress) returns null.
Cast the current ViewModel root
selfVM.RootObject is not given one fixed type because selfVM is available in different ViewModels. When you know the type of the object that opened the ViewModel, cast the root before accessing its members.
selfVM.RootObject->safeCast(Thing).SomeString:='a new value'
In this example, the cast makes SomeString available as a member of Thing.
Preserve a subtype result from an assignment
The assignment operator := has the type of its left-hand side. When you assign a newly created subtype to a property declared as its superclass, cast the assignment result if the following expression needs the subtype type.
For example, RegulatoryAffair is a superclass of Biocide:
(self.Product.RegulatoryAffair:=Biocide.Create).safeCast(Biocide)
The assignment returns a value typed as RegulatoryAffair. safeCast(Biocide) restores the subtype type for the surrounding expression.
Alternatively, keep the created subtype in a variable and return that variable:
let x:=Biocide.Create in(
self.Product.RegulatoryAffair:=x;
x
)
See let for temporary references in OCL expressions.
safeCast compared with a type test
Use safeCast when you need an object reference typed as the subtype. Use oclIsKindOf when you only need a Boolean answer about whether an object is a given type or one of its subtypes.
| Need | Use | Example |
|---|---|---|
| A Boolean type check | oclIsKindOf
|
self.address.oclIsKindOf(USAddress)
|
| A reference on which to use subtype members | safeCast
|
self.address.safeCast(USAddress)
|
