Alex Van Liew
Alex Van Liew

Reputation: 1369

Implictly casting a dynamic object at runtime

Say I have the following code:

class MyField : DynamicObject 
{
     public dynamic Value { get; private set; }

     public override bool TryConvert(ConvertBinder binder, out object result)
     {
         result = binder.Type == Value.GetType() ? Value : null;
         return result != null;
     }

     public MyField(dynamic v) 
     {
          Value = v;
     }
}
// ...
public static class Program
{
    static void doSomething(ulong address) { /* ... */ }

    public void Main(string[] args)
    {
         dynamic field = new MyField((ulong)12345);
         doSomething(field); // fails as field is not a ulong.
         doSomething((ulong)field); // succeeds as field can be casted to a ulong.
         ulong field2 = field; // also succeeds
    }
}

Is there a way to get the first call to doSomething to succeed? I'm writing a library to read a particular file format which uses serialized C-style structures; reading the file entails reading these saved structure definitions and then "populating" them with the data contained in the rest of the file. I have a "structure" DynamicObject class (to support dot-notation access) and a "field" DynamicObject class, which is primarily necessary to hold additional information on the contents of the field; although I could probably get rid of it, it would make certain other operations more difficult. What I'd like to do is just "pretend" MyField is a certain type (well, technically just any built-in primitive or array of primitives, including 2D arrays) and implicitly convert it to that type. However, the runtime fails to try to implicitly convert field to the type required by the underlying method signature if field doesn't match the type required.

Upvotes: 0

Views: 195

Answers (2)

Alex Van Liew
Alex Van Liew

Reputation: 1369

In the vein of Greg's answer, I came up with a solution that makes the runtime happy. It's not exactly what I was originally looking for, but it seems like the best solution.

Since I already have a large if-else tree in my source wherein I take an array of bytes and interpret them as an actual value-type, and indeed my current source does use an underlying generic MyField<T>, so this works fine. I can't recall why I wanted MyField to be dynamic in the first place.

Anyway, this is a modified solution.

class MyField<T>
{
    public dynamic Value { get; private set; }

    public MyField(dynamic v) { Value = v; }

    public static implicit operator T(MyField field)
    {
        return (T)field.Value;
    }
}

I keep coming back to wanting the runtime to just figure out what it needs to cast MyField to at runtime but I guess it's not that big of a deal. If anyone comes up with something better, let me know. I'm going to keep this question open in the meantime.

Upvotes: 1

Greg
Greg

Reputation: 11478

You potentially might want to look into Generics. Coupled with an interface may make the dynamic usage far more viable.

public interface Helper <TInput, TOutput>
{
     <TOutput> DoSomething(TInput input);
}

So when you use this interface with a class, you'll implement your type for both input and output. Which will give you quite a bit of flexibility, which should avoid those cast that you mentioned earlier. A small example, I mean you could obviously adjust it based on needs but I still don't understand what you're trying to really do.

Upvotes: 0

Related Questions