用于初始化类型的类型参数方法...为什么这是无效的?

时间:2018-06-14 15:02:06

标签: c# .net oop

我尝试做的事例

public class Program
{
    public static void Main()
    {

    }

    private static T Initialize<T>() where T : MyInterface
    {
        if (typeof(T) == typeof(MyImplementation))
        {
            return new MyImplementation();  
        }
        throw new NotSupportedException("Unsupported type");
    }
}

public interface MyInterface
{

}

public class MyImplementation : MyInterface
{

}

对我而言,这似乎应该有效(编译器应该知道NewImplementationT,因为TMyInterface)。

  

无法隐式转换类型&#39; MyImplementation&#39;到了&#39;

为什么这是错的?什么是正确的方法?

3 个答案:

答案 0 :(得分:4)

返回类型T可能不是MyImplementation,例如,如果我们有其他类型MyOtherImplementation

public class MyOtherImplementation : MyInterface { }

然后我们调用Initialize<T>方法,这将返回MyOtherImplementation

MyOtherImplementation myInterface = Initialize<MyOtherImplementation>();

您需要将返回类型更改为以下内容,以使其按预期运行:

    private static MyInterface Initialize<T>() where T : MyInterface
    {
        if (typeof(T) == typeof(MyImplementation))
        {
            return new MyImplementation();
        }
        throw new Exception("Unsupported type");
    }

答案 1 :(得分:1)

作为Kevin Smith答案的替代方案,您可以将new添加到where中,即确保每个T类都有默认构造函数

// "where ..., new" - each T must have a default constructor
private static T Initialize<T>() where T : MyInterface, new {
  if (typeof(T) == typeof(MyImplementation)) {
    return new T(); // <- now we can create T which is in fact MyImplementation
  }
  throw new NotSupportedException("Unsupported type");
}

答案 2 :(得分:0)

凯文的答案必须解决你的问题。

但是,如果由于任何原因您不想更改方法的签名,您可以轻松地将对象转换为T然后将其返回。

在主叫方面是相同的,并且在方法主体兼容。

private static T Initialize<T>() where T : MyInterface
{
    if (typeof(T) == typeof(MyImplementation))
    {
        MyInterface obj = new MyImplementation(/*parameters*/);
        return (T)obj;
    }
    throw new NotSupportedException("Unsupported type");
}

当你必须传递参数时,这将处理场景,同时实例化一个我不确定Dmitry逼近的对象!