我的问题的本质是有一个序列化的对象来自我解析的数据库。我将有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;
}
但后来我正在构建一个很长的构造函数。所以我觉得我很好奇,如果语言可以缩小从基类到继承的范围,以假设它的属性,但我认为它不能。
答案 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, ...)
),但该决定由您决定。