简单的一般误解

时间:2013-01-01 12:19:36

标签: c# .net generics casting generic-constraints

你能帮我理解那些情况下的错误吗?

public interface IGeneralInterface
{
}


public class A : IGeneralInterface
{
}

public class B : IGeneralInterface
{
}

public class SomeClass<TGenericType> where TGenericType : IGeneralInterface
{
    private TGenericType internalValue;

    public SomeClass(TGenericType InitValue)
    {
        internalValue = InitValue;
    }

    public TGenericType CreateAnother()
    {
       TGenericType val1 = new B();   //Error here: class B() could not be converted to TGenericType
       return val1;
    }
}

即使我将SomeClass<T>构建为

SomeClass<IGeneralInterface> someClass = new SomeClass<IGeneralInterface>();

我明确传递基接口以包含所有(?)个案,但它仍然会抛出错误

3 个答案:

答案 0 :(得分:3)

更改

 TGenericType val1 = new B();   //Error here: class B() could not be converted to TGenericType

  IGeneralInterface val1 = new B();   

您正在尝试将IGeneralInterface版本TGenericType添加到TGenericType,这是导致错误的原因。

ISpecificInterface可能有其他约束,例如它继承自B不继承的public class SomeClass< TGenericType> where TGenericType : IGeneralInterface, ISpecificInterface TGenericType val1 = new B(); // TGenericType should be ISpecificInterface also, B is not. 。在这种情况下,赋值变为无效。

示例:

IGenericInterface

以上运行。 TGenericType应始终比 public class SomeClass <IGenericInterface> 更具体。

is

或者,您可以使用TGenericType关键字来确定对象是否可以分配给TGenericType val1 = default(TGenericType); var val = new B(); if ( val is TGenericType) { val1 = (TGenericType)val; } ,然后使用转换。

CreateAnother()

编辑以下评论

  

它如何在运行时有额外的要求?我放在这里列出的编译器中的所有内容

B创建类型SomeClass<C> c = new SomeClass<C(); C another = c.CreateAnother(); // C is not assignable from B. (C is below). But It would be valid, if compiler did not flag the error public class C : IGeneralInterface, IDisposable { } 的实例,该实例不是通用的。 以下为例

{{1}}

答案 1 :(得分:1)

为什么您认为new B()应该可转换为TGenericType?关于TGenericType唯一知道的是它实现了接口。

例如,new B()无法转换为A类型。

我不知道你想要获得什么,但你可以将通用约束更改为:

public class SomeClass<TGenericType>
    where TGenericType : class, IGeneralInterface, new()

然后可以在你的create方法中说new TGenericType()

但是不再可能使用类型SomeClass<IGeneralInterface>,因为该接口没有可访问的无参数实例构造函数(当然,没有接口可以有构造函数)。

答案 2 :(得分:0)

代码中的问题是您要声明变量

val1 

的类型

TGenericType

然后尝试通过不同类型的对象实例化它。

即使您已经声明了类的泛型类型必须位于IGeneralInterface的继承层次结构中的条件,它们对于编译器也是不同的。我假设在这个设置中你必须使用显式的强制转换。