Обобщающий код делегата (C #) - PullRequest
4 голосов
/ 13 мая 2011

У меня есть два очень похожих класса, которые делают одно и то же. Единственное отличие состоит в том, что обработчик обратного вызова предоставляется экземпляру каждого класса. Обработчики обратного вызова различны и принимаются с разными параметрами. Я хотел бы обобщить большую часть кода из этих классов в базовый класс. Любые идеи о том, как разумно обобщить код делегата? Я на .NET 2.0

Примечание: Я прочитал этот очень полезный блог о наследовании с делегатами и статьи о ковариации и контравариантности с делегатами, но я до сих пор не понимаю, как эти знания могут быть применены здесь .


public class A
{
    public delegate void AHandler(string param1, string param2);
    public void AcceptHandler(string param3, AHandler handler);
    public void InvokeHandler(string forParam1, string forParam2);

    // the rest is same
}

public class B
{
    public delegate void BHandler(int param1);
    public void AcceptHandler(int param2, int param3, int param4, BHandler handler);
    public void InvokeHandler(int forParam1);

    // the rest is same
}

РЕДАКТИРОВАТЬ:"остальная часть" кода точно так же, за исключением вызовов методов делегатов, которые имеют разные подписи. Примерно так:


public void StartListening()
{
   Timer timer = new Timer(CheckForChanges, null, 0, 1000);            
}

private void CheckForChanges()
{
    // pull changes, and pass different params to InvokeHandler()
}

1 Ответ

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

Почему бы не настроить его следующим образом:
Редактировать : я обновил, чтобы включить методы из вашего редактирования.

public abstract class AbstractBase {
    // "the rest"
    public void StartListening() {
        Timer timer = new Timer(CheckForChanges, null, 0, 1000);            
    }
    protected abstract void CheckForChanges();
}

public class A : AbstractBase {
    public delegate void AHandler(string param1, string param2);
    public void AcceptHandler(string param3, AHandler handler);
    public void InvokeHandler(string forParam1, string forParam2);
    protected override void CheckForChanges() {
        //Do stuff for this version of the class
    }
}

public class B : AbstractBase {
    public delegate void BHandler(int param1);
    public void AcceptHandler(int param2, int param3, int param4, BHandler handler);
    public void InvokeHandler(int forParam1);
    protected override void CheckForChanges() {
        //Do stuff for this version of the class
    }
}

Таким образом, вы получитевесь ваш код, который одинаков в одном классе, а затем отдельные классы A и B могут иметь любую форму методов, которые вам нужны.

Или вы ищете способ вызватьделегаты вообще независимо от того, какой класс?

т.е.Что-то вроде:

AbstractBase ab = new A();
ab.InvokeDelegate();
...