简体   繁体   English

如何基于C#<4中的参数运行时类型调度方法?

[英]How do I dispatch to a method based on a parameter's runtime type in C# < 4?

I have an object o which guaranteed at runtime to be one of three types A , B , or C , all of which implement a common interface I . 我有一个对象o ,它在运行时保证是ABC三种类型之一,所有这些都实现了一个通用接口I I can control I , but not A , B , or C . 我可以控制I ,但不能控制ABC (Thus I could use an empty marker interface, or somehow take advantage of the similarities in the types by using the interface, but I can't add new methods or change existing ones in the types.) (因此我可以使用空标记接口,或者通过使用接口以某种方式利用类型中的相似性,但我无法添加新方法或更改类型中的现有方法。)

I also have a series of methods MethodA , MethodB , and MethodC . 我还有一系列MethodAMethodBMethodC The runtime type of o is looked up and is then used as a parameter to these methods. 查找o的运行时类型,然后将其用作这些方法的参数。

public void MethodA(A a) { ... }
public void MethodB(B b) { ... }
public void MethodC(C c) { ... }

Using this strategy, right now a check has to be performed on the type of o to determine which method should be invoked. 使用此策略,现在必须对o的类型执行检查以确定应调用哪个方法。 Instead, I would like to simply have three overloaded methods: 相反,我想简单地有三个重载方法:

public void Method(A a) { ... } // these are all overloads of each other
public void Method(B b) { ... }
public void Method(C c) { ... }

Now I'm letting C# do the dispatch instead of doing it manually myself. 现在我让C#执行调度,而不是自己手动执行。 Can this be done? 可以这样做吗? The naive straightforward approach doesn't work, of course: 当然,天真直白的方法不起作用:

Cannot resolve method 'Method(object)'. 无法解析方法'Method(object)'。 Candidates are: 候选人是:

  • void Method(A) 无效方法(A)
  • void Method(B) 无效方法(B)
  • void Method(C) void方法(C)

If you can refactor this, move the method to the interface and have each class has its implementation: 如果你可以重构它,将方法移动到接口并让每个类都有它的实现:

I i = o as I;
i.Method();

How about something like this? 这样的事怎么样?

private Dictionary<Type, Action<I>> _mapping = new Dictionary<Type, Action<I>>
{ 
  { typeof(A), i => MethodA(i as A)},
  { typeof(B), i => MethodB(i as B)},
  { typeof(C), i => MethodC(i as C)},
};

private void ExecuteBasedOnType(object value)
{
    if(_mapping.ContainsKey(value.GetType()))
       _mapping(value.GetType())(value as I);
}

If the 3 class A, B and C implements the interface I you should do nothing. 如果A类,B类和C类实现接口I,则不应该执行任何操作。 It's the runtime that choose the right method for you: 运行时为您选择正确的方法:

A a = new A();
class.Method(a); // will calll Method(A a)

B b = new B();
class.Method(b); // will call Method(B b)

Preseumably O is declared as type/interface I then instantiated as either ab or c. 据推测,O被声明为类型/接口,然后将其实例化为ab或c。 The way to do it would be to have a single public method the took a param of type I and then do your logic within that method eg call private method AB or C. 这样做的方法是使用单个公共方法获取类型I的参数,然后在该方法中执行您的逻辑,例如调用私有方法AB或C.

Reading your edited post, o is of type object, remember to be clear when you take about an object becuase as well as being ac# type it is a generic oop term for an instance of a class. 阅读你编辑过的帖子,o是对象类型,记得当你拿到一个对象时要清楚,因为它是一个ac#type它是一个类的实例的通用oop术语。

Why are you declaring it as an object, rather than an i, might it be something else later? 你为什么宣称它是一个对象,而不是一个i,以后可能是其他的东西?

If so to use your overloaded methods you would have to unbox it before calling the method. 如果是这样使用重载方法,则必须在调用方法之前将其取消装箱。 eg 例如

if (o.GetType() == typeof(a))
{
   oa = (a)o;
   Method(oa);
}
else if(o.GetType() == typeof(b))
{
    ...
}

Etc. 等等。

Alternatively if you made the method take a paramater of type i you could do something like: 或者,如果你让方法采用i型的参数,你可以做类似的事情:

i oi = (i)o;
Method(oi);

But you would still need to do something like the the first example within your public method. 但是你仍然需要像公共方法中的第一个例子那样做。

I'm not 100% sure if this will work in your scenario, but it sounds like you might be able to use partial classes: 我不是100%确定这是否适用于您的场景,但听起来您可以使用部分类:

public interface IMethodCallable
{
    public void Method();
}

public partial class A : IMethodCallable
{
    public void Method()
    {
        ....
    }
}

then for the usage: 然后用于:

object o = getObject(); // we know this is A, B or C
((IMethodCallable)o).Method();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 C# 中用基于运行时动态类型的通用调度替换枚举上的 switch 语句? - How do I replace a switch statement over an enum with runtime-dynamic type-based generic dispatch in C#? 如何在运行时将方法附加到动态创建的C#类型? - How do I attach a method to a dynamically-created C# type at runtime? 如何在运行时(C#+ Unity)将方法添加到ANY事件的调用列表中 - How do I add a method to ANY event's invocation list at runtime (C# + Unity) 如何编写C#方法以返回Func <T> 基于枚举参数? - How do I write a C# method to return a Func<T> based in an enum parameter? 如何根据 c# 中方法的参数设置数组的大小? - How do i set the size of an array based on a parameter of a method in c#? C#-在通用方法中使用运行时定义的类型作为参数 - C# - Use runtime-defined type as parameter in generic method 如何将多态性与泛型类型一起使用,该泛型类型的类型参数是 C# 中类型参数约束的子类型? - How do I use polymorphism with a generic type who's type argument is a child of the type parameter constraint in c#? 给定参数的ParameterInfo时,如何检查服务方法的参数类型是否为输出类型? - How do I check if a service method's parameter type is an output type given the parameter's ParameterInfo? 如何在c#中为方法添加参数注释 - how do I add parameter comments for a method in c# 基于运行时参数类型的方法动态选择 - Dynamic selection of method based on runtime parameter type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM