铸造代表

时间:2010-08-12 06:07:00

标签: c#

我对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....
    }
.....

除非使用相同的委托作为类型,否则我不知道如何使此转换工作。 但是在我的项目中,代表的名称会更加漂亮(因为它们存在于不同的类中。

希望你能帮助我。

2 个答案:

答案 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必须加框,从而阻止直接转换