public abstract class SomeBaseClass {}
public class SomeSpecificClass: SomeBaseClass {
public int propertyA;
public string propertyB;
}
public delegate void Callback<T>(T data);
public class Foo {
void MethodA <T> (Callback<T> theInstance) where T: SomeBaseClass {
MethodB(theInstance);
}
void MethodB(Callback<SomeBaseClass> theInstance) {
}
void MethodC() {
Callback<SomeSpecificClass> cb = (data) => {};
MethodA(cb);
}
void MethodD <T> (T theInstance) where T: SomeBaseClass {
MethodE(theInstance);
}
void MethodE (SomeBaseClass theInstance) {
}
}
在 MethodA
中产生错误:
Argument 1: cannot convert from 'Callback<T>' to 'Callback<SomeBaseClass>' [Assembly-CSharp]
Callback<T> theInstance
但是 MethodD 可以很好地将它的实例传递给 MethodE
为什么我不能通过通用 Callback<T>
MethodA 中的实例到 Callback<SomeBaseClass>
类型的参数在 MethodB 中,当我指定 T 扩展 SomeBaseClass 的约束时
最佳答案
基本上,您不能这样做,因为它不安全。
假设我们有一个派生自 SomeBaseClass
的具体类:
public class SomeOtherSpecificClass {}
假设我们更改您的 MethodB
到:
void MethodB(Callback<SomeBaseClass> theInstance)
{
theInstance(new SomeOtherSpecificClass());
}
那应该可以编译,对吧?毕竟,你只是传递一个 SomeOtherSpecificClass
进入Callback<SomeBaseClass>
,这应该没问题。
然后如果我调用 MethodA
像这样:
Callback<SomeSpecificClass> callbcak = data => Console.WriteLine(data.propertyA);
MethodA(callback);
... 那么如果所有这些都被允许,我们将传递一个 SomeOtherSpecificClass
进入一个期待 SomeSpecificClass
的代表.
你的 MethodD
和 MethodE
例子很好,因为MethodE
只能使用 SomeBaseClass
的成员...但是一个Callback<SomeSpecificClass>
真的需要 SomeSpecificClass
, 所以你不能把它当作一个接受 SomebaseClass
的方法.
为了更简单地展示这一点:
// This is valid...
string text = "";
object obj = text;
// This isn't...
Action<string> stringAction = text => Console.WriteLine(text.Length);
Action<object> objectAction = stringAction;
// ... because it would allow this:
objectAction(new object());
关于c# - 在泛型 (Y) 方法中使用泛型 (X) 委托(delegate),其中 Y 扩展了一些基类。无法转换为基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45672857/