none
How to Obtain Generic Class from Interface? RRS feed

  • Question

  • At a given point in my code, I have access to an Interfaced object (IProperty) that does not expose the "Value" of the object even though I can see the "Value" through intelliSense. The class is defined as Property<T> which implements the IProperty interface. Unfortunately, the IProperty interface does not expose the "Value" property and there would be many changes to add it.

    It seems like I should be able to cast the IProperty object to Property<T> and pull the Value from there.  The following code works in the Immediate window but I can't always assume <string>. 

        ? ((Property<string>)Properties[property.Name]).Value

    How can I easily pull the Value object from the Property class even though it isn't exposed by the IProperty interface with the complication of the Generic method?  Make sense? 

    Saturday, December 19, 2015 3:27 AM

Answers

  • "How can I easily pull the Value object from the Property class even though it isn't exposed by the IProperty interface with the complication of the Generic method?"

    You can't, at least not in a reasonable manner. It can be done using reflection but I wouldn't consider that reasonable. Though if you don't have any alternative...

    The interface should have a Value property of type object. If you can't assume that the value has a certain type then a strongly typed Value property wouldn't do you much good anyway.

    • Proposed as answer by Magnus (MM8)MVP Saturday, December 19, 2015 9:45 AM
    • Marked as answer by DaveIII Monday, December 21, 2015 8:14 PM
    Saturday, December 19, 2015 7:42 AM
    Moderator
  • I agree with Mike Danes. There is no reasonable way of doing this. When you cast an object from one type to another, you need to know the target type. And a generic type is basically just a blueprint for a type. Property<T> is not some kind of base class for Property<string> and Property<int>. These are two totally different types.

    If you cannot add the Value property to the interface for some reason and have to cast at runtime, you will have to use reflection. Here is an example for you:

    IProperty p1 = new Property<string>() { Value = "1" };
                IProperty p2 = new Property<int>() { Value = 1 };
    
                Type typeArgument = p2.GetType().GenericTypeArguments[0];
                Type genericType = typeof(Property<>)
                               .GetGenericTypeDefinition()
                               .MakeGenericType(typeArgument);
    
                object o = Convert.ChangeType(p2, genericType);
                int value = (int)genericType.GetProperty("Value").GetValue(o, null); //=1
    

    Hope that helps.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    • Marked as answer by DaveIII Monday, December 21, 2015 8:14 PM
    Saturday, December 19, 2015 9:45 AM

All replies

  • "How can I easily pull the Value object from the Property class even though it isn't exposed by the IProperty interface with the complication of the Generic method?"

    You can't, at least not in a reasonable manner. It can be done using reflection but I wouldn't consider that reasonable. Though if you don't have any alternative...

    The interface should have a Value property of type object. If you can't assume that the value has a certain type then a strongly typed Value property wouldn't do you much good anyway.

    • Proposed as answer by Magnus (MM8)MVP Saturday, December 19, 2015 9:45 AM
    • Marked as answer by DaveIII Monday, December 21, 2015 8:14 PM
    Saturday, December 19, 2015 7:42 AM
    Moderator
  • I agree with Mike Danes. There is no reasonable way of doing this. When you cast an object from one type to another, you need to know the target type. And a generic type is basically just a blueprint for a type. Property<T> is not some kind of base class for Property<string> and Property<int>. These are two totally different types.

    If you cannot add the Value property to the interface for some reason and have to cast at runtime, you will have to use reflection. Here is an example for you:

    IProperty p1 = new Property<string>() { Value = "1" };
                IProperty p2 = new Property<int>() { Value = 1 };
    
                Type typeArgument = p2.GetType().GenericTypeArguments[0];
                Type genericType = typeof(Property<>)
                               .GetGenericTypeDefinition()
                               .MakeGenericType(typeArgument);
    
                object o = Convert.ChangeType(p2, genericType);
                int value = (int)genericType.GetProperty("Value").GetValue(o, null); //=1
    

    Hope that helps.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    • Marked as answer by DaveIII Monday, December 21, 2015 8:14 PM
    Saturday, December 19, 2015 9:45 AM