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

C# 有没有比通过注入使用基类更好的方法将继承属性从基类快速获取到继承类?,c#,inheritance,polymorphism,C#,Inheritance,Polymorphism,我的问题的本质是,有一个来自我解析的数据库的序列化对象。我将有int和DateTime字段以及其他字段。我有四个基类型的不同子类型的等价物。因此,可以这样想,因为它们每个都有不同的字段,但共享Id和DateCreated。我希望节省时间,而不是让一个长的构造函数插入所有这些值,只需执行以下操作: var base = new BaseTest(101, DateTime.Now.Date); X inherited = (X)base; public X(string desc, int va

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

var base = new BaseTest(101, DateTime.Now.Date);
X inherited = (X)base;
public X(string desc, int val, int baseId, DateTime created) : base(baseId, created)
{
  Desc = desc;
  Val = val;
}
但是,当然,这在.NET中是不允许的,所以我想知道-我是否可以使用基类作为一个完整的DTO对象进行注入?是的,我能做到,但我没有通过嗅觉测试。我觉得我解决问题的方法不对,所以我很好奇是否有人有更好的想法。最终的目标是重用一个Id和DateTime字段,这可以在我知道子类型对象是什么之前完成,然后在没有长构造函数的情况下以某种方式输入它。到目前为止,我有:

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();
    }
  }
我可以将构造函数更改为如下内容:

var base = new BaseTest(101, DateTime.Now.Date);
X inherited = (X)base;
public X(string desc, int val, int baseId, DateTime created) : base(baseId, created)
{
  Desc = desc;
  Val = val;
}

但是我要做一个长的构造函数。因此,我想我真的很好奇,这种语言是否可以将范围从基类缩小到继承类,以假定它的属性,但我认为它不能。我在一些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
和其他属性构建。这还有一个奇怪的副作用,即允许从
Baz
Foo
属性构建
Bar

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
}

最后,您甚至可以省略
Bar(Foo Foo,…)
构造函数中的附加参数,并使用属性初始化语法(
newbar(Foo){Name=“John”}
),但这一决定由您来决定。

仅为了设置r/w属性,您根本不需要构造函数,只需使用新的X{BaseId=1,…}@SirRufo是的,我意识到了这一点。我想要的更多的是,如果一个变形是可能的,或者一个DTO相当于在一次突袭中做四个或五个。有点像:“好吧,我把我的父对象建立起来,知道它有四个属性。现在它存在了,我可以重复使用它来注射到实例a、B、C或D中。”而不是做a(int-val){BaseId=BaseId,DateTime=created},B(十进制val,string desc){BaseId=BaseId,DateTime=created}。如果我已经有了这些信息,我只是试图避免重复调用。我想这可能是不可能的。