C#是泛型类型约束的泛型类型 [英] C# is generic type with generic type constraint
问题描述
让我们看看一个接口
interface IOwnedBy< T> T:IOwner
{
T Owner {get; }
}
和
接口IOwner
{
public int Id {get; }
}
在我的代码中,我想要执行以下操作:如果(obj是OwnedBy< IOwner>)
{
DoSomethingWith(obj.Owner.Id);如果(obj是OwnedBy
}
基本上,我想检查obj是否是任何OwnedBy实现。由于IOwner是任何泛型参数的类型约束,所以我认为这是可行的。但是这个条件从来没有满足。
任何方式都不用反射?
在 T
中更改接口是协变的: interface IOwnedBy< out T> T:IOwner
{
T Owner {get; }
}
obj是OwnedBy< IOwner>
失败,因为编译器无法知道其是否安全; IOwnedBy
被声明为不变。如果你明确地告诉编译器它是协变的,那么它就会知道转换是安全的并且可以工作。
为什么它在不变的界面中不安全?考虑以下内容:
interface IOwnedBy< T> T:IOwner
{
T Owner {get; }
void SetOwner(T Owner);
}
class Person:IOwner {}
class Cat:IOwner {}
Cat tom = ...
IOwnedBy< Person> owned = ...
var nope =作为IOwnedBy拥有< IOwner>;
nope.SetOwner(tom); //哎哟!只需将猫设置为IOwnedBy的所有者< Person>
Let's asume an interface
interface IOwnedBy<T> where T : IOwner
{
T Owner { get; }
}
and
interface IOwner
{
public int Id { get; }
}
Somewhere in my code, I would like to do the following:
if (obj is OwnedBy<IOwner>)
{
DoSomethingWith( obj.Owner.Id );
}
Basically, I want to check whether obj is any OwnedBy implementation. As IOwner is the type constraint of any generic parameter, I thought this one would work. But the condition is never met.
Any way without using alot of reflection?
Change the interface to be covariant in T
:
interface IOwnedBy<out T> where T : IOwner
{
T Owner { get; }
}
obj is OwnedBy<IOwner>
fails because the compiler can't know if its safe; IOwnedBy
is declared as invariant. If you explicitly tell the compiler that it is covariant, it then knows that the conversion is safe and it will work.
And why is it unsafe in a invariant interface? Consider the following:
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>
这篇关于C#是泛型类型约束的泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!