【问题标题】:Common base class initialization通用基类初始化
【发布时间】:2012-11-29 05:59:21
【问题描述】:

以场景为例

BaseA -> SubB -> SubSubC

说明:SubSubC 类继承了 SubB 类。 SubB类继承BaseA类

BaseA -> SubD -> SubSubE

说明:SubSubE 类继承 SubD 类。 SubB类继承BaseA类

所以..上..

因此,有许多类的祖父类为 BaseA 。 BaseA 类具有所有方法共有的一些属性。例如:CustomerID、LastLogin、UniqueName 等。

这就是我正在使用的服务中类的设计方式。

我的疑问是在调用服务方法时,所有方法都需要任何 SubSub 类的参数。谁能告诉我,有什么办法可以在一个地方为 BaseA 的属性赋值,这样在创建 SubSub 对象时我就不需要每次都填充基本属性?

我使用 C# 作为我的语言。

代码:

public class BaseA
    {
        public int CustomerId { get; set; }
        public string UniqueName { get; set; }
    }

    public class SubB : BaseA
    {
    }
    public class SubSubC : SubB
    {

    }

    public class SubD : BaseA
    {
    }
    public class SubSubE : SubD
    {

    }

    public class MyMain
    {
        public void SendRequestToService1()
        {
            (new MyServiceObject()).ServiceMethod1(new SubSubC());
        }

        public void SendRequestToService2()
        {
            (new MyServiceObject()).ServiceMethod2(new SubSubE());
        }
    }

在上面的代码中,在 SendRequestToService1 和 SendRequestToService2 中,我需要初始化基类属性 CustomerId 和 UniqueName。 例如:

(new SubSubC(){ CustomerId=2, UniqueName="XXBB" });

如果有很多方法,我需要每次为它们各自的类初始化这些属性。有没有一种方法可以在一个地方初始化基本属性 CustomerId 和 UniqueName,以便继承类(此处为 SubSubC,SubSubE)在创建对象时无需初始化?

【问题讨论】:

  • 不确定问题是什么。看起来像“我想在一个函数中初始化 BaseA 类实例的属性,我可以写吗?”...演示您面临的问题的示例代码会有所帮助。

标签: c# oop design-patterns inheritance


【解决方案1】:

您是否在寻找以下功能?

    //dummy class replacing the service object and it's methods
    public class MyServiceObject
    {
        public void ServiceMethod1(SubSubC param)
        { }
        public void ServiceMethod2(SubSubE param)
        { }
    }

    public class BaseA
    {
        public int CustomerId { get; set; }
        public string UniqueName { get; set; }
    }

    public class SubB : BaseA
    {
    }
    public class SubSubC : SubB
    {
    }

    public class SubD : BaseA
    {
    }
    public class SubSubE : SubD
    {
    }

    public class MyMain
    {
        //declare the SubSub objects
        //SubSubC subSubC;
        //SubSubE subSubE;
        BaseA baseA;

        public MyMain()
        {
            //assign the values to each class in the MyMain contrsuctor
            baseA = new BaseA { CustomerId = 2, UniqueName = "XXBB" };

        }

        public void SendRequestToService1()
        {
            var subSub=new SubSubC();
            (new MyServiceObject()).ServiceMethod1(Initialize(subSub));
        }

        public void SendRequestToService2()
        {
            var subSub = new SubSubE();
            (new MyServiceObject()).ServiceMethod2(Initialize(subSub));
        }

        private T Initialize<T>(T subSub) where T:BaseA
        {
            subSub.CustomerId = baseA.CustomerId;
            subSub.UniqueName = baseA.UniqueName;
            return subSub;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyMain myMain = new MyMain();
            myMain.SendRequestToService1();
            myMain.SendRequestToService2();
        }
    }

【讨论】:

  • 您明白了,但您在 MyMain 构造函数中多次分配 CustomerId,UniquName。在我的情况下,SubSubC 和的 CustomerId 和 UniqueName 将是相同的(可能来自会话) SubSubE。在这种情况下,您能否让我知道,而不是每次创建 subsubC、subsubE 等对象时分配 CustomerId 和 UniqueName 属性,我可以在一个地方执行此操作,这样我就不需要在创建对象时一次又一次地分配它。
  • 是的,很好。但请注意,正如我的问题中提到的,这些是我正在使用的服务中定义的类。所以我没有办法改变它。
  • 这个分辨率怎么样? private T Initialize&lt;T&gt;(ref T subSub) where T:BaseA 应该会变魔术。
  • 这里不需要ref 关键字,特别是因为您要返回正在初始化的对象。但即使该方法是 void 方法,您也不需要 ref 关键字。此外,如果您将其设置为 void 方法,则不需要在上一条评论中提出的建议中的 type 参数。
【解决方案2】:

你问的是调用基本构造函数吗?如果是这样:

class SubSubC : SubB
{
    public object CProperty { get; private set; }
    public SubSubC(object cProperty, string bProperty, int id) : base(bProperty, id)
    {
        CProperty = cProperty;
    }
}
class SubB : BaseA
{
    public string BProperty { get; private set; }
    public SubB(string bProperty, int id) : base(id)
    {
        BProperty = bProperty;
    }
}
class BaseA
{
    public int ID { get; private set; }
    public BaseA(int id)
    {
        ID = id;
    }
}

或者您是在询问如何在方法中初始化对象?如果是这样(假设 setter 在以下代码中是公开的,与前面不同):

void SetSubSubCProperties(SubSubC c, object cProperty, string bProperty, int id)
{
    c.CProperty = cProperty;
    SetSubBProperties(c, bProperty, id);
}
void SetSubBProperties(SubB b, string bProperty, int id)
{
    b.BProperty = bProperty;
    SetBaseAProperties(b, id);
}
void SetBaseAProperties(BaseA a, int id)
{
    a.ID = id;
}

好的,亚历克斯·菲利波维奇的回答,看起来您想通过从不同派生类的实例复制基类属性来初始化派生类的实例。在这种情况下,为了减少亚历克斯答案中的重复,您可以这样做:

void Initialize(BaseA source, BaseA target)
{
    target.CustomerID = source.CustomerID;
    target.UniqueName = source.UniqueName;
}

然后,修改他的例子:

public void SendRequestToService1()
{
    var subSub = new SubSubC();
    Initialize(this.baseA, subSub);
    (new MyServiceObject()).ServiceMethod1(subSub);
}

public void SendRequestToService2()
{
    var subSub = new SubSubE();
    Initialize(this.baseA, subSub);
    (new MyServiceObject()).ServiceMethod2(subSub);
}

【讨论】:

  • 感谢您的回复。这是为了初始化继承类中的基类属性。我在服务中有这些类,我想在将子类作为参数发送给服务之前初始化基类属性(在一个公共位置)。
  • @clklachu 所以......答案是否足够,或者它是否以某种方式错过了你的观点?
  • 我觉得可能有更好的答案可以适合我的情况。
  • @clklachu 如果您能解释它的不足之处,我将能够更好地改进我的答案。我添加了对 Alex Filipovici 答案的修改,消除了他引入的一些多余的并发症。
【解决方案3】:

不确定我是否理解您的问题。

public class A {
  public int ID { get; set; }
}

public class B : A {
}

你可以先B b = new B() 然后b.ID = 12


或者,如果您有一个方法在您的服务中获取A 类型的参数,您可以以相同的方式更改该值。

public void doSomething(A a) {
  a.ID = 12;
}

并使用B - doSomething(new B()) 的实例调用方法

【讨论】:

    猜你喜欢
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    • 2021-03-09
    相关资源
    最近更新 更多