C#代码用于处理具有相同方法名称的不同类

假设您有两个不同的C#类AB ,虽然不是从相同的基类派生,但是为方法共享一些相同的名称。 例如,两个类都有connectdisconnect方法,以及其他几个类。 我希望能够编写一次适用于这两种类型的代码。

这是我想要做的简化示例:

 public void make_connection(Object x) { x.connect() ; // Do some more stuff... x.disconnect() ; return ; } 

当然,这不会编译,因为Object类没有connectdisconnect方法。

有没有办法做到这一点?

UPDATE。 我应该从一开始就明确这一点:我只有A和B的DLL,而不是源代码。

您可以使用界面来完成您想要的操作。

 interface IConnectable { void Connect(); void Disconnect(); } 

AB都应该实现IConnectable 。 然后使用IConnectable而不是Object作为方法的参数类型,您应该全部设置。

 public void MakeConnection(IConnectable connectable) { connectable.Connect(); // Do some more stuff... connectable.Disconnect(); } 

编辑:由于您没有源代码,因此您有以下几种选择:

  1. 使用Max的使用dynamic关键字的解决方案(如果您使用的是.NET 4.0)
  2. 使用Steve的使用cast和if / else语句的解决方案
  3. AB创建包装类,让它们实现接口(或者为它们使用通用的抽象基类)

例如:

 class AWrapper : IConnectable { private A obj; public AWrapper(A obj) { this.obj = obj; } public void Connect() { this.obj.Connect(); } public void Disconnect() { this.obj.Disconnect(); } // other methods as necessary } 

BWrapper类似,只使用B而不是A

然后你可以创建包装器并将它们传递给MakeConnection 。 这取决于你想要的方式。 根据您的情况,一种方法可能比其他方法更容易。

这将在C#4中起作用:

 public void make_connection(dynamic x) { x.connect() ; // Do some more stuff... x.disconnect() ; return ; } 

尝试使用接口。

看看接口(C#参考)和接口(C#编程指南)

所以像

 public interface IConnections { void connect(); void disconnect(); } public class A : IConnections { public void connect() { //do something } public void disconnect() { //do something } } public class B : IConnections { public void connect() { //do something } public void disconnect() { //do something } } public void make_connection(IConnections x) { x.connect(); // Do some more stuff... x.disconnect(); return; } 

有一个OOAD概念‘程序到一个不实现的接口’ ,这让你避免了inheritance层次结构的链

1-您可以创建一个interfcae

 interface IConnection { void Connect(); void Disconnect(); } 

2-让你的类实现这个接口,如下所示。

 class A : IConnection { #region IConnection Members public void Connect() { // your connect method implementation goes here. } public void Disconnect() { // your disconnect method implementation goes here. } #endregion } class B : IConnection { #region IConnection Members public void Connect() { // your connect method implementation goes here. } public void Disconnect() { // your disconnect method implementation goes here. } #endregion } 

3-完成实现后,您可以使函数接受IConnection的参数,如下所示。

 public void makeConnection(IConnection con) { con.Connect(); con.Disconnect(); } 

4-从客户端代码中,您可以传递实现IConnect接口的类的对象。

如果无法使用接口解决方案(例如,您没有源代码),另一种不太有效的解决方案是使用reflection。

正如其他人所说,重新分解使用接口或使用动态方法可能是最优雅的方式。

如果这不可能,您可以将对象强制转换为您的类型。 我建议使用as然后检查演员是否有效,如果有人用无法演员的类型调用此演员,那么未经检查的演员会很危险。

例如,如果类型AB都有一个名为DoSomething()的方法,那么这将有效……

  public static void CallDoSomething(object o) { A aObject = o as A; if (aObject != null) { aObject.DoSomething(); return; } B bObject = o as B; if (bObject != null) { bObject.DoSomething(); return; } } 

说实话,这真是太丑了……我真的会尝试重构接口。

要么必须使用Zach和astander所示的接口(或Base类),要么在使用之前必须使用对象:

 public void make_connection(Object x) { ((A)x).connect() ; // Do some more stuff... x.disconnect() ; return ; } 

您还可以使用reflection来调用方法

你想要的是鸭子打字 。

来自维基百科:

Duck typing是一种动态类型,其中对象的当前方法和属性集确定有效语义,而不是从特定类或特定接口的实现inheritance。

正如其他人所说,C#4.0允许使用dynamic关键字