Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String cast not working

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'.

like image 330
DeeRain Avatar asked Jul 31 '12 10:07

DeeRain


3 Answers

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

like image 33
Rune FS Avatar answered Nov 09 '22 18:11

Rune FS


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;
like image 51
Marc Gravell Avatar answered Nov 09 '22 19:11

Marc Gravell


You can try to change the last line to:

string c = (string)((MyString)b);
like image 2
user854301 Avatar answered Nov 09 '22 17:11

user854301