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

时间:2010-10-29 05:15:06

标签: c#

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

以下是我想要做的简化示例:

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

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

有办法做到这一点吗?

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

9 个答案:

答案 0 :(得分:26)

您可以使用界面来完成您想要做的事情。

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的使用强制转换和if / else语句
  3. 的解决方案
  4. AB创建包装类,让它们实现接口(或者为它们使用通用的抽象基类)
  5. 例如:

    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。这取决于你想要的方式。根据您的情况,一种方法可能比其他方法更容易。

答案 1 :(得分:11)

这适用于C#4:

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

答案 2 :(得分:2)

尝试使用界面。

查看interface (C# Reference)Interfaces (C# Programming Guide)

类似

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;
}

答案 3 :(得分:1)

有一个OOAD概念'Programe到一个接口而不是一个实现',这让你避免了继承层次结构链

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接口的类的对象。

答案 4 :(得分:1)

如果无法使用接口解决方案(例如,您没有源代码),另一种效率较低的解决方案是使用反射。

答案 5 :(得分:1)

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

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

E.g。如果类型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;
        }
    }

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

您也可以使用反射来调用方法

答案 8 :(得分:0)

您想要的是Duck Typing

来自维基百科:

  

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

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