Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在泛型方法中返回一个类的对象_C#_Generics - Fatal编程技术网

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

C# 在泛型方法中返回一个类的对象,c#,generics,C#,Generics,我有一个场景,其中有两个类,分别是ClassA和ClassB,方法是MethodA和MethodB。我必须编写一个泛型方法,根据某个整数变量(比如x)的条件返回上述类的对象实例。当我尝试下面的代码时,我得到一个错误,上面写着“不能隐式地将ClassA转换为T”或“不能隐式地将ClassB转换为T” 通用方法 public T MethodGeneric<T>() { int x; ClassA objectA = new ClassA(); ClassB ob

我有一个场景,其中有两个类,分别是ClassA和ClassB,方法是MethodA和MethodB。我必须编写一个泛型方法,根据某个整数变量(比如x)的条件返回上述类的对象实例。当我尝试下面的代码时,我得到一个错误,上面写着“不能隐式地将ClassA转换为T”或“不能隐式地将ClassB转换为T”

通用方法

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

    if(x==2)
    {
        return objectA;
    }
    else
    {
        return objectB;
    }
}
publictmethodgeneric()
{
int x;
ClassA objectA=新的ClassA();
ClassB objectB=新的ClassB();
如果(x==2)
{
返回对象a;
}
其他的
{
返回对象b;
}
}

问题是
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;
    }
}

问题是
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;
    }
}
从你的角度看,这是封闭的,你是封闭的。您正在将
object
作为类型参数传递,它将再次返回与您案例中的
object
相同的
T
。这就是为什么不能使用
ClassA
对象上定义的属性。相反,您应该传递所需的类型,如
ClassB
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; 
}
如果
inti
决定返回哪个对象,那么为什么要使用泛型呢?你很可能会:

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)检查类型

如果您想在
ClassB
ClassC
对象上分配属性
bValue
cValue
,那么您应该在
ClassA
中写入这些属性

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

从关闭的开始,您就关闭了。您正在将
object
作为类型参数传递,它将再次返回与您案例中的
object
相同的
T
。这就是为什么不能使用
ClassA
对象上定义的属性。相反,您应该传递所需的类型,如
ClassB
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; 
}
如果
inti
决定返回哪个对象,那么为什么要使用泛型呢?你很可能会:

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)检查类型

如果您想在
ClassB
ClassC
对象上分配属性
bValue
cValue
,那么您应该在
ClassA
中写入这些属性



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

给ClassA和B一个通用的基类或接口,并将T限制为该类型。-或者直接强制转换:“return(T)objectA;”等等。@500 InternalServerError然后当有人说
MethodGeneric
时,他们会把你的名字回复过来作为回应。我想我明白你的意思,但从示例中根本看不出类型参数的用途。@500 InternalServerError同意。你的名字让这个笑话太简单了,我忍不住。给ClassA和B一个通用的基类或接口,并将t限制为那个类型。-或者直接抛出:“return(t)objectA;”等等@500 InternalServerError然后当有人说
MethodGeneric
时,他们会把你的名字作为回应。我想我明白你的意思了,但是从这个例子中根本看不出类型参数的用途。@500 InternalServerError同意。你的名字让这个笑话太简单了,我忍不住。我认为你无论如何也不能用那种方式来施展
return(t)objectA
。您需要首先将其推送到object
return(T)(object)objectA但是我同意其他的。如果他想在原始类型上按名称调用特定于类型的方法,这一切都是徒劳的。需要一个更抽象的层次。@ AsayyA-是的,除非有一个已定义的契约,这是没有意义的,就像一个可以使用的接口。@ ReeCopSee关于接口示例,你会考虑一个接口还是一个抽象的基础W/Virtual RunRIDs更合适?有时我会对什么时候应该使用一个而不是另一个感到困惑。@asawyer这取决于-如果类型更多的是“is-a”类型的关系,我会使用一个基类,如果共享信息更多的是行为(即:“充当”)。我认为你无论如何都不能用这种方式转换
返回(t)objectA
。您需要首先将其推送到object
return(T)(object)objectA但是我同意其他的。如果他想在原始类型上按名称调用特定于类型的方法,这一切都是徒劳的。需要一个更抽象的层次。@ AsayyA-是的,除非有一个已定义的契约,这是没有意义的,就像一个可以使用的接口。@ ReeCopSee关于接口示例,你会考虑一个接口还是一个抽象的基础W/Virtual RunRIDs更合适?有时我会对何时使用一个而不是另一个感到困惑。@asawyer这取决于-如果类型更多地是“is-a”类型的关系,我会使用基类,如果共享信息更多地是行为(即:“充当”),我会使用接口。