Использовать делегат вместо интерфейса - PullRequest
5 голосов
/ 13 мая 2011

Я читал, что вы можете использовать интерфейсы и делегаты для той же цели.Например, вы можете использовать делегатов вместо интерфейсов.

Может кто-нибудь привести пример?Я видел пример в краткой книге, но не помню, и хотел спросить.

Можно ли предоставить пример кода?Вариант использования?

Спасибо.

Ответы [ 3 ]

8 голосов
/ 13 мая 2011

Если ваш интерфейс имеет один метод, то удобнее использовать делегат.

Сравните следующие примеры:

Использование интерфейса

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));
}
2 голосов
/ 13 мая 2011

Делегаты могут использоваться так же, как интерфейс с одним методом:

interface ICommand
 {
   void Execute();
 }

delegate void Command();
0 голосов
/ 13 мая 2011

При использовании делегата:

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

Вариант использования - укажите вещь , которая может выполнять только одно действие,Делегаты хороши тем, что вам не нужно создавать новые классы, вы можете просто взять метод с той же сигнатурой или даже передать лямбду, которая вызывает метод с другой сигнатурой.Но интерфейсы более гибкие, если вы решите получить более сложную логику:

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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...