参数必须是输入安全错误
Parameter must be input-safe error
这是我的一段代码:
public interface IA<in TInput>
{
void Method(IB<TInput> entities);
}
public interface IB<in T> { }
我不明白为什么会出现以下编译错误:
"Parameter must be input-safe. Invalid variance: The type parameter |TInput| must be contravariantly valid on "IB".
任何帮助将不胜感激。
C# 中的逆变指示符(即 in
)仅在直接级别上是直观的,当您使 "takes in" 成为泛型类型参数的方法时。然而,在内部,逆变意味着关系 (Q&A with an explanation) 的 反转 ,因此在 IA
中使用 in
使其与 IB
不兼容.
这个问题最好用一个例子来说明。考虑 class Animal
及其派生的 class Tiger
。我们还假设 IB<T>
有一个方法 void MethodB(T input)
,它是从 IA
的 Method
:
调用的
class A_Impl<T> : IA<T> {
T data;
public void Method(IB<TInput> entities) {
entities.MethodB(data);
}
}
声明IA<in TInput>
和IB<in TInput>
意味着你可以
IA<Animal> aForAnimals = new A_Impl<Animal>();
IA<Tiger> aForTigers = aForAnimals;
IA<in TInput>
有一个方法接受IB<TInput>
,我们可以这样调用:
aForTigers.Method(new B_Impl<Tiger>());
这是个问题,因为现在 A_Impl<Animal>
将 Animal
传递给需要 Tiger
.
的接口的 MethodB
你对 IB<out T>
没有问题,但是 - 协变和逆变:
public interface IB<out T> {
// ^^^
}
// This works
public interface IA<in TInput> {
void Method(IB<TInput> x);
}
// This works too
public interface IC<out TInput> {
void Method(IB<TInput> x);
}
这是我的一段代码:
public interface IA<in TInput>
{
void Method(IB<TInput> entities);
}
public interface IB<in T> { }
我不明白为什么会出现以下编译错误:
"Parameter must be input-safe. Invalid variance: The type parameter |TInput| must be contravariantly valid on "IB
任何帮助将不胜感激。
C# 中的逆变指示符(即 in
)仅在直接级别上是直观的,当您使 "takes in" 成为泛型类型参数的方法时。然而,在内部,逆变意味着关系 (Q&A with an explanation) 的 反转 ,因此在 IA
中使用 in
使其与 IB
不兼容.
这个问题最好用一个例子来说明。考虑 class Animal
及其派生的 class Tiger
。我们还假设 IB<T>
有一个方法 void MethodB(T input)
,它是从 IA
的 Method
:
class A_Impl<T> : IA<T> {
T data;
public void Method(IB<TInput> entities) {
entities.MethodB(data);
}
}
声明IA<in TInput>
和IB<in TInput>
意味着你可以
IA<Animal> aForAnimals = new A_Impl<Animal>();
IA<Tiger> aForTigers = aForAnimals;
IA<in TInput>
有一个方法接受IB<TInput>
,我们可以这样调用:
aForTigers.Method(new B_Impl<Tiger>());
这是个问题,因为现在 A_Impl<Animal>
将 Animal
传递给需要 Tiger
.
MethodB
你对 IB<out T>
没有问题,但是 - 协变和逆变:
public interface IB<out T> {
// ^^^
}
// This works
public interface IA<in TInput> {
void Method(IB<TInput> x);
}
// This works too
public interface IC<out TInput> {
void Method(IB<TInput> x);
}