使用委托代替接口

6

我读到可以使用接口和委托来达到相同的目的。例如,你可以使用委托代替接口。

有人可以提供一个例子吗?我在《Nutshell》书中看到过一个例子,但我忘记了,想问问。

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

谢谢。


3
可能是C#如何使委托和接口方法可互换的重复问题。 - H H
3个回答

8
如果你的接口只有一个方法,那么使用委托更加方便。
比较以下示例:

使用接口

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

Using a delegate

// 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<int, Func<int, int>> op = a => b => a + b; Console.WriteLine(op(1)(2)); - phoog
@phoog, @user177883:phoog所展示的是所谓的柯里化,即将一个接受多个参数的函数转换为一系列接受单个参数的函数链。这是λ演算中使用的非常强大的技术。可以通过接口方法返回单个方法接口来进行类比。 - vgru

2

委托可以像单方法接口一样使用:

interface ICommand
 {
   void Execute();
 }

delegate void Command();

0

当您使用委托:

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
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接