6

我希望这听起来像是一个显而易见的问题,但是委托返回类型是否也必须与它所委托的方法的返回类型相匹配?

例如,像这样:

public static void Save()
    {
        TS ts = new TS(SaveToDatabase);
    }

    public delegate void TS();

    private static void SaveToDatabase()
    { }

这永远行不通

public static void Save()
    {
        TS ts = new TS(SaveToDatabase);
    }

    public delegate string TS();

    private static void SaveToDatabase()
    { }
4

4 回答 4

7

是的,它必须返回相同的类型并具有相同的参数。换句话说,函数和委托声明必须具有相同的签名。

例子:

    //Declare delegate (return double with double param)
    public delegate double Squared(double x);

    public class Circle
    {
        private double _radius;


        public static double ValueTimesValue(double Value)
        {
            return Value * Value;
        }

        public double Area(Squared sqd)
        {
            return sqd(_radius) * Math.PI;
        }

        public void CircleCharacteristics()
        {
            Squared Sq = new Squared(ValueTimesValue);
        }
    }

编辑: If you see the sample code, Squared Delegate and ValueTimesValue function have the same return type and parameters.

于 2012-12-10T14:05:08.940 回答
5

来自msdn

委托允许您将函数作为参数传递。委托的类型安全要求您作为委托传递的函数具有与委托声明相同的签名。

还有来自C# 规范的另一个引用:

如果以下两个都为真,则方法和委托类型是兼容的:

  • 它们具有相同的编号或参数、相同的类型、相同的顺序、相同的参数修饰符。
  • 它们的返回类型是相同的。

我认为它很好地描述了兼容性条件。如您所见,您的代码违反了第二个条件,这会产生编译器错误。

于 2012-12-10T14:08:49.837 回答
2

简单来说,委托是方法的模板(希望我不会因为过于简单而受到抨击)。如果你想要一个可视化,把它想象成一把锁,而物理实现就像一把钥匙。一把钥匙适合某把锁,但在另一把锁中失效。就像钥匙不适合错误的锁一样,应用不同模板(签名)的方法也会失败。

所以,是的,您需要为您希望“委派工作”的方法提供正确的签名。如果您想更多地从软件方面考虑,委托是它所代表的物理实现的契约,就像接口是它所代表的实际方法的契约一样。它们是非常相似的概念。

于 2012-12-10T14:10:30.530 回答
1

其实不一定。参数的类型和结果只能匹配。所以你可以这样做:

class Argument : BaseArgument    {    }

class BaseArgument    {    }

class BaseResult    {    }

class Result : BaseResult    {    }

delegate BaseResult MyDelegate(Argument argument);

class Test
{
    public Test()
    {
     var d1 = new MyDelegate(Method1);

    }

    Result Method1(BaseArgument a)
    {
        return null;
    }
}

通过匹配,我的意思是返回类型的协方差,因此方法可以返回更专业的(派生)类型,然后委托声明 - 委托需要 BaseResult 所以结果是好的。并且参数的逆变,因此委托说将提供 Argument,因此方法可以将 BaseArgument 声明为参数,因为 Argument 是 BaseArgument。

于 2012-12-10T14:20:39.963 回答