对不同的类型调用相同的方法

本文关键字:方法 调用 类型 | 更新日期: 2023-09-27 18:05:36

Edit:让我们假设这些类实际上共享一个接口!这是我的重大失误……


由于我不知道的原因,有两个WPF类,它们都有相同的签名相同的方法:

  • UIElement
  • Animatable

所以我一直在想(对于它的检查)我应该如何构造一个方法(例如typechecking &异常),最终调用上述方法。

(我将张贴我将倾向于做什么,但我正在寻找什么更有经验的人会推荐。)

对不同的类型调用相同的方法

我的方法:

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

在您建议的情况下,两个类共享同一个接口IAnimatable

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

应该足够

这是文档

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

在编辑了两个不从同一接口继承的类之后,答案是使用以下方法之一:

    反射
  1. 动态

当然,这些在运行时之前都不会检查方法是否存在,但我认为这在问题中是隐含的。

给定以下两个类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方法,调用将在运行时失败。

编译器不会帮助(或阻止)你的动态。失败被延迟到运行时:)