views:

47

answers:

2

B"H

I know its a bit of a mouthful and may not be totally understandable. So here is an example of what I am trying to do.

public class TypeWithString
{
    public string MyString { get; set; }
}

string s = "We Want Moshiach Now";
TypeWithString tws = new TypeWithString();
object o = s;
dynamic d = tws;
d.MyString = o;

This code surprisingly generates an error RuntimeBinderException: Cannot implicitly convert type 'object' to 'string'. Even though MyString is of type string and what is being held in o is a string.

is this a bug or a shortcoming in the DLR?

Is there a way to get around it?

If I do not know the type ahead of time. But I do know that it complies with duck typing. i.e. I know that it implements an unwritten interface. Is there anyway I can assign one variable to the other when they really are the correct type?

Thank you so much

+4  A: 

No, this is expected. The compiler knows the type of o is object, so it records a dynamic action of "try to find a property called MyString and then try to assign a value of type object to it" - it could do that if there were an implicit conversion of object to string, but there isn't. Note that the only part of your statement which is dynamic is the target of it... so that's the only bit which is treated dynamically. At execution time, the "execution-time compiler" will effectively say, "What's the actual type of the value of d? Ah, it's TypeWithString... now, what would happen if we had:

TypeWithString tmpD = (TypeWithString) d;
tmpD.MyObject = o;

... and what would happen would be a compile-time error.

If you want it to behave dynamically in the value as well, just use dynamic instead of object for the value you assign:

string s = "We Want Moshiach Now";
TypeWithString tws = new TypeWithString();
dynamic o = s;
dynamic d = tws;
d.MyString = o;

This time, the "execution-time compiler" will ask itself for the actual type of both d and o values, and imagine code like this:

TypeWithString tmpD = (TypeWithString) d;
string tmpO = (string) o; // Actual type is string at execution time
tmpD.MyObject = tmpO;
Jon Skeet
+1  A: 

You could always try d.MyString = o as string; which will cast (without throwing) o to a string or null if cast doesnt exist.

FallingBullets
B"HI don't know ahead of time what it is going to be. otherwise I would have just stored it in the correct variable.
Rabbi