C#代码用于处理具有相同方法名称的不同类
假设您有两个不同的C#类A
和B
,虽然不是从相同的基类派生,但是为方法共享一些相同的名称。 例如,两个类都有connect
和disconnect
方法,以及其他几个类。 我希望能够编写一次适用于这两种类型的代码。
这是我想要做的简化示例:
public void make_connection(Object x) { x.connect() ; // Do some more stuff... x.disconnect() ; return ; }
当然,这不会编译,因为Object类没有connect
或disconnect
方法。
有没有办法做到这一点?
UPDATE。 我应该从一开始就明确这一点:我只有A和B的DLL,而不是源代码。
您可以使用界面来完成您想要的操作。
interface IConnectable { void Connect(); void Disconnect(); }
A
和B
都应该实现IConnectable
。 然后使用IConnectable
而不是Object
作为方法的参数类型,您应该全部设置。
public void MakeConnection(IConnectable connectable) { connectable.Connect(); // Do some more stuff... connectable.Disconnect(); }
编辑:由于您没有源代码,因此您有以下几种选择:
- 使用Max的使用
dynamic
关键字的解决方案(如果您使用的是.NET 4.0) - 使用Steve的使用cast和
if
/else
语句的解决方案 - 为
A
和B
创建包装类,让它们实现接口(或者为它们使用通用的抽象基类)
例如:
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
然后检查演员是否有效,如果有人用无法演员的类型调用此演员,那么未经检查的演员会很危险。
例如,如果类型A
和B
都有一个名为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关键字