C#是泛型类型约束的泛型类型 [英] C# is generic type with generic type constraint

查看:218
本文介绍了C#是泛型类型约束的泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们看看一个接口

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆