处理GenericType <t>类型的对象而不管T </t>

时间:2011-04-06 11:01:16

标签: c# generics casting

如果两个类具有相同的GenericType&lt;&gt;不管T我想做点什么。这可能吗?

// class is given; I can't change it!!
public class MyGeneric<T> : MyBaseClass where T : struct, IComparable, IConvertible
{
    public T MyProperty { get; set; }
}


public void DoStuff(MyBaseClass objA, MyBaseClass objB)
{
    ...
    if (objA.GetType().IsGenericType && objA.GetGenericTypeDefinition() == typeof(MyGeneric<>) &&
            objA.GetType() == objB.GetType())
    {
        //here I know that my objects do have a "MyProperty"
                //I would like to do something like:
        if (((MyGeneric<T>)objA).MyProperty.CompareTo(((MyGeneric<T>)objB).MyProperty) > 0)  //doesn't work!!!!
        {
            //do stuff
        }
    }
}

2 个答案:

答案 0 :(得分:0)

如果将DoStuff方法签名更改为

,则可以使其正常工作
public void DoStuff<T>(MyBaseClass objA, MyBaseClass objB)
    where T : struct, IComparable, IConvertible
{
    // ...
}

但是,您必须在编译时知道T的类型才能调用该方法;我不确定这是否能解决你的问题。

除此之外,另一种解决方案是使用反射:

var valueA = (IComparable)objA.GetType().GetProperty("MyProperty").GetValue(objA, null);
var valueB = (IComparable)objB.GetType().GetProperty("MyProperty").GetValue(objB, null);
if (valueA.CompareTo(valueB) > 0) {
    // ...            
}

答案 1 :(得分:0)

这真的没有任何意义:

  1. objA.GetType() == objB.GetType()确保他们 属于同一类型,即独立于T
  2. 如果通过简单地删除此检查来解决第1点,那么比较这些属性仍然没有意义,因为在两个实例中唯一相同的是属性的名称。 类型可能不同。应该是什么结果?
  3. 如果你真的想要比较属性,只有当两个实例的T 相同时,才使用这个方法:

    public void DoStuff<T>(MyGeneric<T> objA, MyGeneric<T> objB) 
        where T : struct, IComparable, IConvertible
    {
        if (objA.MyProperty.CompareTo(objB.MyProperty) > 0)
        {
            //do stuff
        }
    }
    

    如果您在编译时不知道T,则可以使用Jon建议的反射,或者如果您使用的是.NET 4,则可以使用新的dynamic关键字:

    public void DoStuff(MyBaseClass objA, MyBaseClass objB) 
    {
        if (objA.GetType().IsGenericType && 
            objA.GetGenericTypeDefinition() == typeof(MyGeneric<>) &&
            objA.GetType() == objB.GetType()
           )
    
        {
            dynamic objADyn = objA;
            dynamic objBDyn = objB;
            if (objADyn.MyProperty.CompareTo(objBDyn.MyProperty) > 0)
            {
                //do stuff
            }
        }
    }