greggorob64
greggorob64

Reputation: 2557

Casting one generic to another, without class constraints

I have the following code:

public interface IDrilldown
{
   void AddCriteria<T>(T Criterion);
}

public class MyClass<W> : IDrilldown // where W : class
{
    void IDrilldown.AddCriteria<T>(T Criterion)
    {
       W value = Criterion as W;
       ...
    }
}

Unfortunately, the cast I have above will not work unless W has the constaint in the code. I would like to have this using value types. Is it at all possible?

I cannot make W and T the same type. My interface does not have a type associated with it globally, only the internal data types.

This is so that I can have a List all having different T's

Upvotes: 4

Views: 2325

Answers (2)

Aaron Barker
Aaron Barker

Reputation: 706

Would the dynamic keyword help you out?

Something like this:

public interface IDrilldown
{
   void AddCriteria<T>(T Criterion);
}

public class MyClass : IDrilldown
{
    void IDrilldown.AddCriteria<T>(T criterion)
    {
       dynamic value = criterion;
       // can use typeof() to figure out type if needed...
       ...
    }
}

Upvotes: 2

Joshua
Joshua

Reputation: 8212

I was able to find a way to do it, it's a little hacky but allows it to work:

class MyClass<W> : IDrilldown {
    void IDrilldown.AddCriteria<T>(T Criterion) {
        if (Criterion is W) {
            W value = (W)Convert.ChangeType(Criterion, typeof(W));
            // value is W, have fun
            // or - as Snowbear pointed out in the comments
            W value = (W)(object)Criterion;
            // works just as well....
        } else {
            // value is NOT W and could not be converted.
        }
    }
}

The only drawback with this is, Convert.ChangeType will use converters to change between internal objects, so string value = (string)Convert.ChangeType(1, typeof(string)) will work and return "1" instead of throwing an exception.

To clarify on how this works, the documentation states:

For the conversion to succeed, value must implement the IConvertible interface, because the method simply wraps a call to an appropriate IConvertible method. The method requires that conversion of value to conversionType be supported.

so for this method to work with custom types you will need to implement the IConvertible interface to convert from one custom type to any other type. In the code sample above, if both T and W are the same type, the Convert.ChangeType will succeed, even if the custom object does not implement IConvertiable.

Upvotes: 2

Related Questions