C#是具有泛型类型约束的泛型类型

时间:2017-07-14 10:28:23

标签: c# generics reflection

让我们假设一个界面

interface IOwnedBy<T> where T : IOwner 
{ 
    T Owner { get; }
}

interface IOwner 
{ 
    public int Id { get; } 
}

在我的代码中的某处,我想执行以下操作:

if (obj is OwnedBy<IOwner>) 
{
    DoSomethingWith( obj.Owner.Id );
}

基本上,我想检查obj是否是任何OwnedBy实现。由于IOwner是任何泛型参数的类型约束,我认为这个可行。但这种情况从未得到满足。

没有使用很多反射的任何方式?

1 个答案:

答案 0 :(得分:7)

将界面更改为T中的协变:

interface IOwnedBy<out T> where T : IOwner 
{ 
    T Owner { get; }
}

obj is OwnedBy<IOwner>失败,因为编译器无法知道其安全; IOwnedBy被声明为不变量。如果你明确地告诉编译器它是协变的,那么知道转换是安全的并且它将起作用。

为什么在不变的界面中它不安全?请考虑以下事项:

interface IOwnedBy<T> where T : IOwner 
{ 
    T Owner { get; }
    void SetOwner(T Owner);
}

class Person: IOwner { }
class Cat: IOwner { }

Cat tom = ...

IOwnedBy<Person> owned = ...
var nope = owned as IOwnedBy<IOwner>;
nope.SetOwner(tom); //Ouch! Just set a cat as an owner of a IOwnedBy<Person>