我正在实现一个Web控件,它使用某个函数获取一个对象(作为参数) - 让我们称之为DoStuff() - 该对象可以属于不同的类,这些类都是从抽象类派生的 - 我们称之为SuperClass - 这个SuperClass没有DoStuff()方法。
所以我的问题是:如果对象中存在此方法而不必将其强制转换为派生类,那么C#中是否有一种方法可以在运行时调用Object的方法。
类似的东西(我知道这不起作用,但我认为它更好地表达了我想要完成的事情):
if(myObject.Functions["DoStuff"] != null){
myObject.executeFunction("DoStuff");
}
这一切都可能吗?
答案 0 :(得分:3)
可以通过反思来实现,例如:
uses System.Reflection
....
public void ExecuteMethod(object thing, string method)
{
Type type = thing.GetType(); //gets the runtime type of the object
MethodInfo mi = type.GetMethod(method); // null if method not found
mi.Invoke(thing, null); //invokes the method on the "thing" object,
//passing null arguments, and returns the result
}
但是,在您的场景中,最好(如果可能)创建一个具有IDoStuff
方法的接口DoStuff
,并使所有可能被调用的类实现它。
这样,您的代码将更简单,更不容易出错,如下所示:
public void ExecuteDoStuff(object thingy)
{
if (thingy is IDoStuff)
((IDoStuff)thingy).DoStuff();
else
throw new Exception("thingy cannot do stuff");
}
答案 1 :(得分:2)
好吧,在C#4中你可以写:
dynamic d = myObject;
d.DoStuff();
如果DoStuff()
方法无法绑定,则会抛出异常,但只在执行时检查
相对相对棘手的是要知道这是否会在没有这样做的情况下发挥作用 - 你当然可以抓住例外,但这并不理想。
你可以尝试用反射来找到它,但我再也不认为这是一种想法。
更大的问题是为什么抽象类不具有DoStuff
方法,至少作为抽象方法。那将是远更好的解决方案。
如果只有某些子类具有DoStuff
方法,最好将其放入接口:
public interface IStuffable
{
void DoStuff();
}
然后使适当的子类实现IStuffable
,你可以写:
IStuffable stuffable = myObject as IStuffable;
if (stuffable != null)
{
stuffable.DoStuff();
}
答案 2 :(得分:1)
有几种方法可以做到这一点。我从推荐的开始:
创建一个包含DoStuff()
方法的接口,并在所有类中实现它。然后将您的对象转换为该接口:
interface IDoStuff {
void DoStuff();
}
// call it on your object
((IDoStuff)object).DoStuff();
扩展您的基类以包含DoStuff()
方法(如果可能)
使用反射来调用方法:
object.GetType().GetMethod("DoStuff").Invoke();