C#:是具有继承的泛型类型的运算符

Tob*_*ias 3 c# generics operators

我有一个运算符比较泛型类型的问题.

 public interface ISomeInterface<T> where T : SomeBaseClass{
 }

 public class SomeClass : SomeBaseClass{
 }
Run Code Online (Sandbox Code Playgroud)

现在我们想用is运算符检查类型.我们有一个实现接口ISomeInterface的类的实例.

不幸的是,我们面临以下问题:

 // someObject is an Instance of a class implementing interface ISomeInterface<SomeClass>
 bool isSomeBaseClass = someObject is ISomeInterface<SomeBaseClass>; // false
 bool isSomeClass = someObject is ISomeInterface<SomeClass>; // true
Run Code Online (Sandbox Code Playgroud)

是否可以检查变量泛型类型?

托比,提前谢谢

Dar*_*rov 8

这称为通用协方差,在C#4.0中受支持.您可以T使用out关键字标记泛型参数:

public interface ISomeInterface<out T> where T : SomeBaseClass
Run Code Online (Sandbox Code Playgroud)

但这有一个限制.该T参数只能作为接口中方法的返回类型出现.

Eric Lippert有一系列有关此主题的博客文章,我邀请您阅读.


Oma*_*mar 5

是的,您可以使用inandout关键字来利用协方差和逆变:

public interface ISomeInterface<in T> where T : SomeBaseClass{

}
Run Code Online (Sandbox Code Playgroud)

或者:

public interface ISomeInterface<out T> where T : SomeBaseClass{

}
Run Code Online (Sandbox Code Playgroud)

但请记住,使用关键字in您可以使用T作为参数,否则使用out您可以使用T作为返回类型。

协方差:

A型是协变的时候,你可以从转换X<S>X<B>

逆变:

A型逆变时,你可以从转换X<B>X<S>

- 其中 S 是子类,B 是基类。


我在阅读 C# 4.0 一书时学到的一个有趣的例子是关于堆栈。

class Stack<T>{
   int i;
   T[] array = new T[1000];
   public void Push(T element){
       array[i++] = element;
   }
}

class BaseClass{
}

class SubClass : BaseClass{
}
Run Code Online (Sandbox Code Playgroud)

事实上,它解释了在这种情况下可以使用逆变,当 Stack 实现这个接口时:

interface IPushable<in T>{
    void Push(T element);
}
Run Code Online (Sandbox Code Playgroud)

然后:

IPushable<BaseClass> stackB = new Stack<BaseClass>();
IPushable<SubClass> stackS = stackB;
stackS.Push(new SubClass());
Run Code Online (Sandbox Code Playgroud)

而协方差int这种情况,当Stack实现如下接口时:

interface IPoppable<in T>{
    T Pop();
}
Run Code Online (Sandbox Code Playgroud)

那么:

IPoppable<SubClass> stackS = new Stack<SubClass>();
IPoppable<BaseClass> stackB = stackB;
BaseClass baseClass = stackB.Pop();
Run Code Online (Sandbox Code Playgroud)

这真的很有帮助,因为它允许向上转换和向下转换而不会出现任何问题和编译时错误。