在泛型方法中返回一个类的对象

时间:2012-06-05 17:32:12

标签: c# generics

我有一个场景,其中有两个类分别使用方法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;
    }
}

2 个答案:

答案 0 :(得分: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之外,这不会保护您。

如果ClassAClassB都来自相同的基类或接口,则可以使这更安全,因为您可以设置一个通用约束来减少出错的可能性。然而,这仍然不是一种完全安全的工作方式,因为仿制药不合适。最好让两个类都实现一个接口(即:IClassBase),然后不使用泛型,但返回接口:

public IClassBase CreateInstance()
{
    //... 
         return objectA; // This will work fine, provided ClassA implements IClassBase
}

答案 1 :(得分:0)

从你关闭的this double-post开始,你就近了。您将object作为类型参数传递,它将在您的案例中再次返回T object。这就是为什么你不能使用ClassA对象上定义的属性。相反,您应该传递所需的类型,例如ClassBClassC。可能是这样的:

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; 
    }
}

但要抓住的是你必须从来电方(Main)检查类型。

如果您想在bValuecValue对象上分配属性ClassBClassC,那么您应该在ClassA中编写这些属性。

此外,您只使用get访问者,还需要set来分配值。

相关问题