有没有比通过注入使用基类更快地从基类获取继承属性到继承类的方法?

时间:2017-07-20 16:54:31

标签: c# inheritance polymorphism

我的问题的本质是有一个序列化的对象来自我解析的数据库。我将有int和DateTime字段以及其他字段。我有相当于基本类型的四种不同的子类型。因此,请考虑它们,因为它们各自具有不同的字段,但共享Id和DateCreated。我想节省时间,而不是让一个很长的构造函数来插入所有这些值,只需执行以下操作:

var base = new BaseTest(101, DateTime.Now.Date);
X inherited = (X)base;

但是,当然,这在.NET中是不行的,所以我想知道 - 我可以只使用BaseClass作为注入的全开DTO对象吗?是的我能做到,但它没有通过我的气味测试。关于它的一些东西似乎是关闭的,我觉得我正在以错误的方式解决问题,所以如果有人有更好的想法我很好奇。最终目标是重用Id和DateTime字段,这可以在我知道SubType对象之前完成,然后只是在没有长构造函数的情况下以某种方式提供它。到目前为止,我有这个:

public class BaseTest
  {
    public int BaseId { get; set; }
    public DateTime Created { get; set; }

    public BaseTest() { }

    public BaseTest(int baseId, DateTime created)
    {
      BaseId = baseId;
      Created = created;
    }
  }

  public class X : BaseTest
  {
    public string Desc { get; set; }
    public int Val { get; set; }

    public X(string desc, int val, BaseTest baseValues)
    {
      Desc = desc;
      Val = val;
      BaseId = baseValues.BaseId;
      Created = baseValues.Created;
    }
  }


  class Program
  {
    static void Main(string[] args)
    {
      //This works for a reuse pattern but just doesn't feel right.
      var b = new BaseTest(101, DateTime.Now.Date);
      var p = new X("Test", 1, b);

      Console.ReadLine();
    }
  }

我可以将构造函数更改为:

public X(string desc, int val, int baseId, DateTime created) : base(baseId, created)
{
  Desc = desc;
  Val = val;
}

但后来我正在构建一个很长的构造函数。所以我觉得我很好奇,如果语言可以缩小从基类到继承的范围,以假设它的属性,但我认为它不能。

1 个答案:

答案 0 :(得分:1)

我遇到了一些用于工作的VB.NET代码同样的问题,我对每个类都有一个"方便的初始化构造函数" (其中可能这是一个更好的术语,IIRC它是C ++中的复制构造函数)。我还没有找到一种真正变形的方法,就像你提到的那样(比我可能有一个聪明的人),但我已经提出上述想法(下面的例子)以帮助我保持压力 - 水平下降。

public class Foo
{
    public int Id { get; set; }
    public Foo() {}
    public Foo(Foo foo) { Id = foo.Id; }
}

public class Bar : Foo
{
    public string Name { get; set; }
    public Bar(Foo foo, string name) : base(foo) { Name = name; }
    public Bar(Bar bar) : base(bar) { Name = bar.Name; } // Allows further inheritance
}

这会产生可维护性缺陷:您有两个大多数相同的构造函数,但它允许您执行以下操作:

var foo = new Foo() { Id = 5 }
// Decide that `foo` should now be a `Bar`
var bar = new Bar(foo, "John");

通过这种方式,Bar实际上并不需要了解Foo的内部,只是可以从Foo和其他属性构建它。这也有一个奇怪的副作用,允许从Bar的{​​{1}}属性构建Foo

Baz
public class Baz : Foo
{
    public DateTime BirthDate { get; set; }
    public Baz(Foo foo, DateTime birthDate) : base(foo) { BirthDate = birthDate; }
    public Baz(Baz baz) : base(baz) { BirthDate = baz.BirthDate; } // Allows further inheritance
}

最后,您甚至可以省略var foo = new Foo() { Id = 5 }; var bar = new Bar(foo, "John"); var baz = new Baz(bar, DateTime.UtcNow); 构造函数中的其他参数,并使用属性初始化语法(Bar(Foo foo, ...)),但该决定由您决定。