C# 委托-委托返回类型是否也必须与其委托的方法匹配?

C# 委托-委托返回类型是否也必须与其委托的方法匹配?,c#,delegates,C#,Delegates,我希望这听起来像是一个显而易见的问题,但是,委托返回类型是否也必须与它所委托的方法的返回类型相匹配 例如,像这样: public static void Save() { TS ts = new TS(SaveToDatabase); } public delegate void TS(); private static void SaveToDatabase() { } 这永远不会起作用的地方 public static void

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

例如,像这样:

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()
    { }

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

例如:

    //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);
        }
    }

编辑:
如果您看到示例代码,则平方委托和ValueTimesValue函数具有相同的返回类型和参数。
来自:

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

另一句话来自:

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

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

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

简单来说,委托是方法的模板(希望我不会因为过于简化而受到太大的抨击)。如果您想要可视化,请将其视为一个锁,物理实现就像一把钥匙。一把钥匙适合某一把锁,但在另一把锁上失效。正如密钥不能装入错误的锁一样,应用不同模板(签名)的方法也会失败


因此,是的,对于希望“将工作委托给”的方法,您需要正确的签名。如果您想从软件的角度来考虑,委托是它所表示的物理实现的契约,就像接口是它所表示的实际方法的契约一样。它们是非常相似的概念。

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

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声明为参数,因为参数是BaseArgument。

谢谢-我的进度已经显示了这一点,但如果不熟悉这一点,它就太复杂了。谢谢如果你看到示例代码,平方委托和ValueTimesValue函数都有相同的返回类型和参数,我可能永远都读不懂:)谢谢。我已经阅读了MSDN,并一直在使用他们的例子。它现在慢慢开始有意义了。@DaveRook我在我的答案中添加了C#规范的重要部分,它描述了方法在接口之间进行比较时应该满足+1的条件-现在我完全明白了!谢谢,很高兴我能帮助戴夫。纯粹主义者可能讨厌我,但找到类比往往会让事情更容易理解。:-)我相信在早期的Java时代,可以说是比C#更严格的OO,没有任何东西可以满足委托人的角色。接口是一个很好的比较,因为它们实际上是实现deligate功能所必需的。将对象注册到实现某些“单方法EventInterface”的类中,并在从主机触发事件时调用接口的方法。您甚至可以使用一组“EventInterface”实现来方便多个订阅者。是的,多态性由名为协方差和逆变的机制使用。