2

我有一个场景,其中有两个类分别使用方法 MethodA 和 MethodB 说 ClassA 和 ClassB。我必须编写泛型方法,该方法根据某个整数变量 x 的条件返回上述类的对象实例。当我尝试下面的代码时,我收到一条错误消息,提示“无法将 ClassA 隐式转换为 T”或“无法将 ClassB 隐式转换为 T”

public ClassA
{
    public void MethodA()
    {
        //method implementation
    }
}

public ClassB
{
    public void MethodB()
    {
        //method implementation
    }
}

通用方法为

public T MethodGeneric<T>()
{
    int x;
    ClassA objectA = new ClassA();
    ClassB objectB = new ClassB();

    if(x==2)
    {
        return objectA;
    }
    else
    {
        return objectB;
    }
}
4

2 回答 2

4

问题是T不是ClassA也不是ClassB

您可以尝试通过强制转换来处理这个问题,如下所示:

public static T MethodGeneric<T>() where T : class
{
    int x = 2;
    ClassA objectA = new ClassA();
    ClassB objectB = new ClassB();

    if (x == 2)
    {
        return objectA as T;
    }
    else
    {
        return objectB as T;
    }
}

但是,如果有人打电话给您,这不会保护您MethodGeneric<ClassC>(),除非在这种情况下返回null

如果您拥有ClassA并且ClassB两者都派生自相同的基类或接口,则可以使这更安全,因为您可以放置​​一个通用约束来减少出错的机会。但是,这仍然不是一种完全安全的工作方式,因为泛型不合适。最好让两个类都实现一个接口(即IClassBase:),然后不使用泛型,而是返回接口:

public IClassBase CreateInstance()
{
    //... 
         return objectA; // This will work fine, provided ClassA implements IClassBase
}
于 2012-06-05T17:35:35.870 回答
0

从你这个封闭的双柱中,你很接近。您object作为类型参数传递,它将再次返回与您的情况相同T的参数。object这就是为什么你不能使用ClassA对象上定义的属性。相反,您应该传递所需的类型,例如ClassBor ClassC。可能是这样的:

public T getObject<T>(int i) where T : ClassA
{
    if(i == 1)
    {
        ClassB objB = new ClassB();
        return objB as T;
    }
    else
    {
        ClassC objC = new ClassC();
        return objC as T;
    }
}

public static void main()
{
    var obj = getObject<ClassB>(5); //which wont work anyway since i == 5 !!
    obj.aValue = 20;
    obj.bValue = 30;
    //obj.cValue = 40; this wont work since obj is of type ClassB

    //or 

    var obj = getObject<ClassC>(5);
    obj.aValue = 20;
    //obj.bValue = 30; this wont work since obj is of type ClassC now
    obj.cValue = 40; 
}

我不确定你为什么要检查变量int i来决定应该返回什么类型。这不是对泛型的真正使用。真正使用泛型可能如下所示:

public T getObject<T>(int i) where T : ClassA
{
    return new T(); //without the use of int i
}

如果int i是什么决定了返回哪个对象,那么为什么要使用泛型呢?你可以这样做:

public ClassA getObject(int i)
{
    if(i == 1)
    {
        ClassB objB = new ClassB();
        return objB;
    }
    else
    {
        ClassC objC = new ClassC();
        return objC;
    }
}

public static void main()
{
    var obj = getObject(5);
    if (obj is ClassB)
    {
        obj.aValue = 20;
        obj.bValue = 30;
        //obj.cValue = 40; this wont work since obj is of type ClassB
    }
    //or 

    var obj = getObject(5);
    if (obj is ClassC)
    {
        obj.aValue = 20;
        //obj.bValue = 30; this wont work since obj is of type ClassC
        obj.cValue = 40; 
    }
}

但问题是您必须从调用方(主要)检查类型。

如果你想在和对象上分配属性bValue,那么你应该把这些属性写在.cValueClassBClassCClassA

此外,您仅使用get访问器,还需要set分配值。

于 2012-11-12T07:58:17.687 回答