Consider a class like this:
public class MyString
{
private string _string;
public string String
{
get { return _string; }
set { _string = value; }
}
public MyString(string s)
{
_string = s;
}
public static implicit operator string(MyString str)
{
return str.String;
}
public static implicit operator MyString(string str)
{
return new MyString(str);
}
}
How do I make the following code work?
MyString a = "test";
object b = a;
var c = (string)b;
Now I get this exception:
InvalidCastException: Unable to cast object of type 'MyString' to type 'System.String'.
a custom cast is a function in disguise. Whether an actual cast is performed or a custom conversion operator is called depends on the compile time type of the expression being cast.
In your example the compile time type of the expression being cast Ie. the type of the expression b
is object
the type object
does not have a custom conversion to string. However a cast might be valid and is therefor allowed by the compiler.
MyString a = "test";
object b = a;
var c = (string)b;
string d = a;
var e = (string)a;
The fourth line will be treated as //calls the funciton defined as a custom conversion string d = MyString.op_implicit(a);
The same is true for the fifth line. The fifth line eventhough it uses the syntax for a cast is not a cast it's a conversion.
However the third line looks like a cast and is a cast. A cast is you telling the compiler that you have more information in regards to the runtime type of an object than the compile has. (string)a
tells the compiler that it can rest assured the object represented by a is going to have the runtime type of string. In your case that's not true it has the type MyString
which does not derive from string (and cannot since string is sealed).
The point is that eventhough custom conversions (defined using either implicit or explicit) have the same syntax as casts they are something completely different from a cast. A cast will never leave the inheritance chain (including inheriting interfaces) you can go up or down the chain with a cast but never ever leave it
Custom implicit/explicit operators only work between typed values - not object
. Such a cast is always either a basic type-check or an unbox. The implicit cast is:
string s = a;
You can try to change the last line to:
string c = (string)((MyString)b);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With