C# 在不同类型上调用相同的方法

C# 在不同类型上调用相同的方法,c#,coding-style,types,C#,Coding Style,Types,编辑:让我们假设这些类实际上不共享接口!我这方面的重大失误 由于我不知道的原因,例如,有两个WPF类,它们都具有具有相同签名的相同方法: 因此,我一直在想(为了见鬼),我应该如何构造一个最终调用上述方法的方法(例如typechecking和exceptions) (我将公布我倾向于做的事情,但我正在寻找更有经验的人会推荐的内容。)我的方法: public static void Animate(object target) { target.ThrowIfNull(); //E

编辑:让我们假设这些类实际上不共享接口!我这方面的重大失误


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

因此,我一直在想(为了见鬼),我应该如何构造一个最终调用上述方法的方法(例如typechecking和exceptions)

(我将公布我倾向于做的事情,但我正在寻找更有经验的人会推荐的内容。)

我的方法:

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

对不从同一接口继承的两个类进行编辑后,答案是使用以下选项之一:

  • 倒影
  • 当然,这些都不会检查方法在运行时之前是否存在,但我认为这在某种程度上隐含在问题中

    给定以下两个类A和B,它们包含具有相同签名的方法,但不实现相同的接口:

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

    您可以创建一个方法来处理具有该签名的方法的任何对象,如下所示:

    static void HandleObject(dynamic anything) {
        anything.Handle("It works!");
    }
    
    HandleObject基本上会将任何对象作为输入,并在运行时尝试对其盲目调用名为
    Handle
    的方法。如果对象没有
    句柄
    方法,则调用将在运行时失败


    编译器不会在动态方面帮助(或阻止)您。失败被推迟到运行时:)

    哦,怎么了,我还以为我已经检查了一个公共接口--这有点不幸。感谢你的回答,但我编辑了我的问题,以关注一个不太可能的情况,即没有接口的相当糟糕的体系结构。对不起,我很高兴你这么做了,这是我经常问自己的问题。一定有一个我现在想不起来的常见例子。你知道你想调用哪种方法的实例类型吗?还是对象?@ HAZIKK:只考虑一种方法,它得到一个它想要调用一个特定方法的对象,唯一已知的是方法名称和它的签名,并且该方法存在于某些类型(以名称已知),因此在设计的方法中,输入要么需要被铸造,要么可以尝试反射/动态。这些方法需要
    属性
    动画
    的参数,这会导致相当长的签名。您可以将其他参数封装到单个参数对象()中,以减少签名更新我的答案,添加了带有参数的示例object@hazzik:我认为各个部分的执行时间有一个小问题,在我的方法中,首先检查预防条件,如果不满足条件,则立即抛出异常,在该部分完成后,将创建动画(main方法不应该将
    属性
    动画
    作为参数,它应该在方法中创建,否则整个过程毫无意义),因此,按照您的方式执行时,必须先创建动画,然后才能清楚目标是否可设置动画。@hazzik:(顺便说一句,我没有得到通知,因为您没有使用
    @H.B.
    ,这是必要的,因为Charles也在本评论部分发表了评论)与之类似的是,强制转换是在方法参数中完成的,并且不会为错误的输入类型引发专门的异常。确实如此。看起来我没有很好地阅读您的答案。
    static void HandleObject(dynamic anything) {
        anything.Handle("It works!");
    }