我对c#很陌生,所以我的问题可能很简单,但现在就去了。
我一直在努力与代表合作,并且有点坚持这个问题。
.....
public delegate double delegateA();
public delegate double delegateB();
public static double myFunc()
{
return 0;
}
public static delegateA myTest()
{
return myFunc;
}
static void Main(string[] args)
{
delegateB myFuncDelegate;
myFuncDelegate = myTest(); // <-- Error: Cannot implicitly convert type....
}
.....
除非使用相同的委托作为类型,否则我不知道如何使此转换工作。 但是在我的项目中,代表的名称会更加漂亮(因为它们存在于不同的类中。
希望你能帮助我。
答案 0 :(得分:24)
您无法直接在代理之间进行转换。您可以做的是从现有的兼容的新代表。因此,如果您将代码更改为:
delegateB myFuncDelegate = new delegateB(myTest());
这将有效。 (请注意,“兼容性”并不一定意味着签名相同 - 有关详细信息,请参阅语言规范。)
为了让其他读者稍微清楚一点,这里有一个更简单的完整示例,不需要任何方法调用。
// Two delegate types with the same signature
delegate void Foo();
delegate void Bar();
class Test
{
static void Main()
{
// Actual value is irrelevant here
Foo foo = null;
// Error: can't convert like this
// Bar bar = foo;
// This works fine
Bar bar = new Bar(foo);
}
}
请注意,此“无转换”规则有一个例外 - C#4中的泛型差异。例如,在C#4中,可以写:
Action<object> foo = x => Console.WriteLine(x.GetHashCode());
Action<string> bar = foo;
...因为Action<T>
在T
中是逆变(因此它实际上被声明为Action<in T>
)。这是引用转换 - 它不像第一个示例那样创建 new 委托。但是,这不仅仅适用于“兼容”代表 - 只有通用代理。
答案 1 :(得分:6)
此外,不完全是你所问的,但有趣的是 - 这不起作用:
Func<double> func_double = () => 1;
Func<object> func_object;
func_object = func_double;
但这样做:
Func<string> func_string = () => "hello";
Func<object> func_object;
func_object = func_string;
字符串示例的区别在于使用可以强制转换为对象的引用类型,而double必须加框,从而阻止直接转换