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