【问题标题】:How can I declare two classes so they can be passed to the same function?如何声明两个类以便将它们传递给同一个函数?
【发布时间】:2016-02-15 16:43:10
【问题描述】:

给定以下两个类

public class LocalFoo {

}

public class RemoteFoo {

}

这两个类都应该有相似的属性:

public string strBar{ get; set; }
public int intBar{ get; set; }

不同之处在于这些属性是如何设置和读取的——在前一种情况下,这些属性是由程序在本地处理的。在后者中,属性是直接从数据库中读取和写入的,另外两个是从数据库中读取的DataTable。

我知道继承必须在这里发生,但这就是我卡住的地方。

例如,如果我声明一个方法TakesFoo

public void takesFoo( Foo bar ){
    /*Magic Happens Here*/
}

我希望它能够使用LocalFooRemoteFoo 类型的对象调用该方法。

我知道我可以写一个抽象类 Foo :

public abstract class Foo{
}

并让 LocalFoo 和 RemoteFoo 都从它继承,但有一个警告 - 我有另一个抽象类,我需要 RemoteFoo 来继承它,它用于更容易读取/写入 DataTables -

public abstract class DRHelper : IEquatable<DRHelper>, IDisposable {
}

我最初的直觉是让 Foo 成为一个界面,但我不知道这是否可行,我希望有人能给我一些关于如何处理这个问题的指导。

【问题讨论】:

  • 接口。答案是接口 :) 但是,您应该小心不要为了重用代码而继承。这不是对继承的适当使用(封装通常是代码重用的首选)。
  • “我最初的直觉是让 Foo 成为一个接口” 这样做。
  • @Codor Foo 不需要继承任何东西 - RemoteFoo 需要继承 DRHelper
  • 这里的界面很完美

标签: c# inheritance abstract-class


【解决方案1】:

创建一个 IFoo 接口,该接口具有:

string strBar{ get; set; }
int intBar{ get; set; }

类 LocalFoo 和类 RemoteFoo 都需要实现 IFoo 接口。

然后将您的方法更改为:

public void takesFoo( IFoo bar ){
    /*Magic Happens Here*/
}

【讨论】:

    【解决方案2】:

    我认为,你应该使用Visitor Pattern

    它可以让你避免if(bar is LocalFoo)代码。

        public abstract class Foo
        {
            public abstract void Accept(IVisitor visitor);
        }
    
        public class LocalFoo : Foo
        {
            public override void Accept(IVisitor visitor)
            {
                visitor.Visit(this);
            }
        }
    
        public class RemoteFoo : Foo
        {
            public override void Accept(IVisitor visitor)
            {
                visitor.Visit(this);
            }
        }
    
        public interface IVisitor
        {
            void Visit(LocalFoo foo);
            void Visit(RemoteFoo foo);
        }
    
        public class Visitor : IVisitor
        {
            public void Visit(RemoteFoo foo)
            {
                /*Magic Happens Here*/
            }
    
            public void Visit(LocalFoo foo)
            {
                /*Magic Happens Here*/
            }
        }
    

    【讨论】:

    • 除了我的代码不关心传入的对象是RemoteFoo还是LocalFoo,只要它具有属性strBarintBar即可。
    • 这意味着比乔的答案是正确的答案 - 只需使用一个界面
    • 我知道 - 我必须等待时间过去才能将其标记为正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2011-10-12
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 2018-07-27
    相关资源
    最近更新 更多