简体   繁体   English

无法转换为通用类型C#

[英]Can't cast to generic type c#

I have the following scenario 我有以下情况

public class A
{
}

public class BA : A
{

}

//other subtypes of A are defined

public class AFactory
{
    public T Create<T>() where T : A
    {
        //work to calculate condition
        if (condition)
            return new BA();
        //return other subtype of A
    }
}

The following compilation error is thrown: 引发以下编译错误:

Error CS0029 Cannot implicitly convert type 'B' to 'T' 错误CS0029无法将类型'B'隐式转换为'T'

What's wrong? 怎么了?

Well the cast could easily fail. 好吧,演员阵容很容易失败。 Suppose I have: 假设我有:

public class AB : A {}

B b = new B();
AB ab = b.Create<AB>();

That would end up trying to assign a B reference to a variable of type AB . 最终将尝试为类型AB的变量分配B引用。 Those are incompatible. 这些是不兼容的。

It sounds like you probably shouldn't make Create a generic method. 听起来您可能不应该Create通用方法。 Or maybe you should make A generic: 或者, 也许您应该使A通用:

public abstract class A<T> where T : A
{
    public abstract T Create();
}

public class B : A<B>
{
    public override B Create()
    {
        return new B();
    }
}

That would work - but we don't know what you're trying to achieve, so it may not actually help you. 那行得通-但是我们不知道您要达到的目标,因此它可能实际上对您没有帮助。

Alternatively you could keep your current design, but use: 或者,您可以保留当前的设计,但是使用:

public T Create<T>() where T :  A
{
    return (T) (object) new B();
}

That will then fail if you call Create with a type argument of anything other than object , A or B , which sounds a little odd to me... 如果您使用objectAB以外的任何类型的类型参数调用Create ,那将失败,这对我来说听起来有点奇怪。

T can be any class derived from A . T可以是从A派生的任何类。 There could also be a 也可能有一个

class C : A { }

It matches the generic constraint, but you can't return an instance of B from Create<C>() method. 它与通用约束匹配,但是您不能从Create<C>()方法返回B的实例。

Right. 对。 For creating new B class you should use this code: 要创建新的B类,应使用以下代码:

public class A
{
}

public class B : A
{
    public static T Create<T>() where T : A, new()
    {
        return new T();
    }
}

public class Example
{
    public void DoWork()
    {

        B b = B.Create<B>();
        A a = B.Create<A>();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM