Вызов одного и того же метода для разных типов - PullRequest
2 голосов
/ 14 августа 2011

Редактировать: Предположим, что классы на самом деле не имеют общий интерфейс!Большая ошибка с моей стороны ...


По неизвестным мне причинам есть, например, два класса WPF, каждый из которых имеет одинаковый метод с одинаковой подписью:

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

(в поисках того, что порекомендуют более опытные люди. )

Ответы [ 4 ]

2 голосов
/ 14 августа 2011

Мой подход:

public static void Animate(object target)
{
    target.ThrowIfNull(); //Extension
    if (!(target is Animatable || target is UIElement))
        throw new ArgumentException("The target is not animatable");

    //Construct animation

    (target as dynamic).BeginAnimation(property, animation);
}
1 голос
/ 14 августа 2011

В случае, если вы предложили, оба класса используют один и тот же интерфейс IAnimatable.

((IAnimatable)target).BeginAnimation(property, animation);

Должно быть достаточно

Здесь - документация

0 голосов
/ 14 августа 2011

После редактирования двух классов, не наследующих один и тот же интерфейс, ответом будет использование одного из следующих:

  1. Отражение
  2. Динамический

Ни один из них, конечно, не проверит, что метод существует до времени выполнения, но я думаю, что это как бы подразумевается в вопросе.

Учитывая следующие два класса A и B, которые содержат метод с той же сигнатурой, но не реализуют тот же интерфейс:

class A
    public void Handle(string s) {
        Console.WriteLine("Hello from A: " + s);
    }
}

и:

class B
    public void Handle(string s) {
        Console.WriteLine("Hello from B: " + s);
    }
}

Вы можете создать метод, который обрабатывает любой объект, имеющийметод с такой сигнатурой, например:

static void HandleObject(dynamic anything) {
    anything.Handle("It works!");
}

HandleObject будет в основном принимать любой объект в качестве входных данных, и во время выполнения попытаться слепо вызвать метод с именем Handle для него.Если у объекта нет Handle метода, вызов не будет выполнен во время выполнения.

Компилятор не помогает (или не останавливает) вас в динамике.Отказы откладываются до времени выполнения:)

0 голосов
/ 14 августа 2011
public static void Animate(this object target, DependencyProperty property, AnimationTimeline animation)
{
    target.ThrowIfNull();
    DoAnimate(target as dynamic);
}

private static void DoAnimate(object target, DependencyProperty property, AnimationTimeline animation)
{
    throw new ArgumentException("The target is not animatable")
}

private static void DoAnimate(Animatable target, DependencyProperty property, AnimationTimeline animation)
{
    target.BeginAnimation(property, animation);
}

private static void DoAnimate(UIElement target, DependencyProperty property, AnimationTimeline animation)
{
    target.BeginAnimation(property, animation);
}

На мой взгляд, он чище.

ОБНОВЛЕНО Пример с AnimationContext

class AnimationContext
{
    private readonly DependencyProperty property;
    private readonly AnimationTimeline animation;

    public AnimationContext(DependencyProperty property, AnimationTimeline animation)
    {
        this.property = property;
        this.animation = animation;
    }

    public void Animate(UIElement target)
    {
        target.BeginAnimation(property, animation);
    }

    public void Animate(Animatable target)
    {
        target.BeginAnimation(property, animation);
    }

    public void Animate(object target)
    {
        throw new ArgumentException("The target is not animatable");
    }
}

static class AnimateExtensions
{
    public static void Animate(this object target, DependencyProperty property, AnimationTimeline animation)
    {
        target.ThrowIfNull();
        new AnimationContext(property, animation).Animate(target as dynamic);
    }
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...