更简单的方法来检查和调用重载方法

时间:2011-12-27 18:13:09

标签: c#

private void SomeMethod(DerivedA something) {...}
private void SomeMethod(DerivedB something) {...}
private void SomeMethod(DerivedC something) {...}


BaseClass bc = somevariable;
if (bc is DerivedA) Somemethod(bc as DerivedA)
else if (bc is DerivedB) Somemethod(bc as DerivedB)
else if (bc is DerivedC) Somemethod(bc as DerivedC)
...
else if (bc is DerivedZZ) Somemethod(bc as DerivedZZ)

在.NET 3.5中,必须有一种更简单的方法,不是吗?

4 个答案:

答案 0 :(得分:4)

让SomeMethod成为你班级的成员方法是不合适的?

如果DerivedA,DerivedB等...都共享同一个父级,那么您可以在父类中创建此方法作为虚拟成员方法,并在从其继承的类中覆盖它。 (这不是特定于.NET 3.5或任何其他.NET版本 - 这只是基本的OOP功能之一)

像这样:

public class BaseClass
{
   public virtual void SomeMethod()
   {
       Console.WriteLine ("BaseClass");
   }
}

public class DerivedA : BaseClass
{
    public override SomeMethod()
    {
        Console.WriteLine("DerivedA");
    }
}

public class DerivedB : BaseClass
{
    public override SomeMethod()
    {
       Console.WriteLine ("DerivedB");
    }
}

BaseClass bc = someVariable;

bc.SomeMethod();

答案 1 :(得分:1)

public class BaseClass {
    public virtual void SomeMethod()
    {
    }
};

public class DerivedA : BaseClass {
    public override void someMethod()
    { //Do DerivedA things
    }
};
public class DerivedB : BaseClass {
    public override void someMethod()
    { //Do DerivedB things
    }
};
public class DerivedC : BaseClass {
    public override void someMethod()
    { //Do DerivedC things
    }
};

然后你可以这样做:

BaseClass bc = new BaseClass();

BaseClass bc = new DerivedA();

BaseClass bc = new DerivedB();

BaseClass bc = new DerivedC();

然后致电:

bc.SomeMethod();

即使BC类型是BaseClass,如果实例化为派生类,也会调用派生方法。这意味着继承和多态。

此代码与您的代码相同。

即使是你的,你也可以更好地使用typeof(); ;)

答案 2 :(得分:0)

听起来你需要稍微重新考虑一下你是如何做事的;如果你有一些其他需要使用这个BaseClass的类,在你调用一个方法之前不知道它包含什么类型的派生类,这看起来效率很低。

public abstract class BaseClass
{
     public abstract void InitializeAndDoOtherStuff();
}

public abstract class DerivedA
{
     public overload void InitializeAndDoOtherStuff()
     {
         // Initializes the control, pass whatever you need into this method, etc)
     }
}

在这种情况下,您的代码如下所示:

BaseClass bc = someVariable;
bc.InitializeAndDoOtherStuff();

从代码管理的角度来看,这是一个可怕的想法,但你可以这样做:

 public class DerivedA : BaseClass, IControlA { }
 public class DerivedB : BaseClass, IControlB { }
 ...

然后你的另一个类有这样的重载:

 public void SomeMethod(IControlA control) { }
 public void SomeMethod(IControlB control) { }
 ...

然后,在您的代码中,它将像以下一样简单:

BaseClass bc = someVariable;
SomeMethod(bc);

并且重载解析会处理它,因为适当的接口仅在一个派生类上。

答案 3 :(得分:0)

我也会像其他人已经说过的那样重新设计你的课程,但如果你不能这样做,你可以用反射来完成这项工作

this.GetType().InvokeMember("SomeMethod", // Method name
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
    null, // DefaultBinder
    this, // object to call the method on
    new[]{ bc } // parameters to the method
    );

如果SomeMethod不是公共实例方法,则需要相应地调整BindingFlags。