【问题标题】:Use delegate in place of interface使用委托代替接口
【发布时间】:2011-05-13 16:04:54
【问题描述】:

我读到您可以将接口和委托用于相同目的。例如,您可以使用委托而不是接口。

有人可以举个例子吗?我在简而言之的书中看到了一个例子,但我不记得了,想问一下。

能否提供一些示例代码?用例?

谢谢。

【问题讨论】:

标签: c# interface delegates


【解决方案1】:

如果你的接口只有一个方法,那么使用委托会更方便。

比较以下例子:

使用接口

public interface IOperation
{
    int GetResult(int a, int b);
}

public class Addition : IOperation
{
    public int GetResult(int a, int b)
    {
         return a + b;
    }
}

public static void Main()
{
    IOperation op = new Addition();
    Console.WriteLine(op.GetResult(1, 2));
}

使用委托

// delegate signature.
// it's a bit simpler than the interface
// definition.
public delegate int Operation(int a, int b);

// note that this is only a method.
// it doesn't have to be static, btw.
public static int Addition(int a, int b)
{
    return a + b;
}

public static void Main()
{
    Operation op = Addition;
    Console.WriteLine(op(1, 2));
}

您可以看到委托版本略小。

使用匿名方法和 `Func` 委托

如果将其与内置的 .NET 通用委托(Func<T>Action<T> 和类似方法)以及匿名方法结合使用,则可以将整个代码替换为:

public static void Main()
{
    // Func<int,int,int> is a delegate which accepts two
    // int parameters and returns int as a result
    Func<int, int, int> op = (a, b) => a + b;

    Console.WriteLine(op(1, 2));
}

【讨论】:

  • Func&lt;int, Func&lt;int, int&gt;&gt; op = a =&gt; b =&gt; a + b; Console.WriteLine(op(1)(2));
  • @phoog, @user177883:phoog 演示的内容被称为currying,即将一个接受多个参数的函数转换为一个函数链,每个函数都接受一个参数。这是 lambda 演算中使用的一种非常强大的技术。可以进行一些类比,接口方法返回单个方法接口作为结果。
【解决方案2】:

委托的使用方式与单方法接口相同:

interface ICommand
 {
   void Execute();
 }

delegate void Command();

【讨论】:

    【解决方案3】:

    当你使用委托时:

    public delegate T Sum<T>(T a, T b);
    
    class Program
    {
        static void Main(string[] args)
        {
            int sum = Test.Sum(new[] {1, 2, 3}, (x, y) => x + y);
        }
    }
    
    public static class Test
    {
        public static int Sum<T>(IEnumerable<T> sequence, Sum<T> summator)
        {
            // Do work
        }
    }
    

    当你使用接口时:

    public interface ISummator<T>
    {
        T Sum(T a, T b);
    }
    
    public class IntSummator : ISummator<int>
    {
        public int Sum(int a, int b)
        {
            return a + b;
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            int sum = Test.Sum(new[] {1, 2, 3}, new IntSummator());
        }
    }
    
    public static class Test
    {
        public static int Sum<T>(IEnumerable<T> sequence, ISummator<T> summator)
        {
            // Do work
        }
    }
    

    用例 - 提供一个只能做一个动作的事物。委托很好,因为您不必创建新类,您只需采用具有相同签名的方法,甚至传递一个调用具有不同签名的方法的 lambda。但是如果你决定获得更复杂的逻辑,接口会更灵活:

    public interface IArithmeticOperations<T>
    {
        T Sum(T a, T b);
        T Sub(T a, T b);
        T Div(T a, T b);
        T Mult(T a, T b);
        //
    }
    
    public class IntArithmetic : IArithmeticOperations<int>
    {
        public int Sum(int a, int b)
        {
            return a + b;
        }
    
        public int Sub(int a, int b)
        {
            return a - b;
        }
    
        public int Div(int a, int b)
        {
            return a / b;
        }
    
        public int Mult(int a, int b)
        {
            return a * b;
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            int sum = Test.SumOfSquares(new[] {1, 2, 3}, new IntArithmetic());
        }
    }
    
    public static class Test
    {
        public static int SumOfSquares<T>(IEnumerable<T> sequence, IArithmeticOperations<T> summator)
        {
            // Do work
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-13
      • 2014-08-18
      • 2021-02-20
      • 2020-11-10
      • 2011-01-01
      • 2012-02-11
      • 2012-07-05
      • 2011-02-10
      相关资源
      最近更新 更多