委托 - 委托返回类型是否必须与它委派的方法相匹配?

时间:2012-12-10 14:03:28

标签: c# delegates

我除了这似乎是一个明显的问题但是,委托返回类型是否必须匹配它委派的方法的返回类型?

EG,像这样:

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 个答案:

答案 0 :(得分:6)

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

示例:

    //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.

答案 1 :(得分:5)

来自msdn

  

委托允许您将函数作为参数传递。的类型安全   代理人要求您作为代理人传递的功能   与代表声明相同的签名。

来自C# specification的另一句话:

如果满足以下两个条件,则方法和委托类型是兼容的:

  • 它们具有相同的数字或参数,具有相同的类型,顺序相同,具有相同的参数修饰符。
  • 他们的返回类型相同。

我认为这是对兼容性条件的非常好的描述。正如您所看到的,您的代码违反了第二个条件,这会产生编译器错误。

答案 2 :(得分:2)

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

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

答案 3 :(得分: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所以结果是好的。 和参数的逆变,所以委托说会提供参数,所以方法可以将BaseArgument声明为参数becaulse Argument是BaseArgument。