【发布时间】:2009-01-09 12:49:42
【问题描述】:
我正在用 C# 编写一个数据访问库,我的数据模型类的结构如下(在 DataAccess 程序集中):
public abstract class DataModel {...} (protected constructor)
public abstract class DataClass {...} (protected constructor)
public abstract class DataField {...} (protected constructor)
public class IntegerField : DataField
{
public IntegerField(DataClass cls, string name, bool isNullable,
int? defaultValue, int? minValue, int? maxValue) {...}
}
public class StringField : DataField
{
public StringField(DataClass cls, string name, bool isNullable,
string defaultValue, int maxLength) {...}
}
public class BooleanField : DataField
{
public BooleanField(DataClass cls, string name, bool isNullable,
bool? defaultValue) {...}
}
...
如您所见,每个字段都有不同的构造函数。
要使用它,您可以从 XML 文件自动生成类, 例如,包含“Customer”数据类和“Employee”数据类的“Store”数据模型将生成以下代码:
public class StoreDataModel : DataModel
{
public CustomerDataClass Customer { get; private set;}
public EmployeeDataClass Employee { get; private set;}
public StoreDataModel()
{
Customer = new CustomerDataClass(this);
AddClass(customer)
Employee = new EmployeeDataClass(this);
AddClass(employee)
}
}
public class CustomerDataClass : DataClass
{
public StringField FirstNameField { get; private set; }
public StringField LastNameField { get; private set; }
public DateField BirthDateField { get; private set; }
public CustomerDataClass(StoreDataModel model) : base(model)
{
FirstNameField = new StringField(this, "FirstName", true, null, 50);
LastNameField = new StringField(this, "LastName", true, null, 50);
...
}
}
public class EmployeeDataClass : DataClass {...}
我对这段代码的问题是,由于生成的代码与基本数据模型类位于不同的程序集中,因此 StringField/IntegerField/... 类必须具有公共构造函数,这意味着数据访问程序集之外的任何人都可以创建他们的实例,我想防止这种情况发生。
由于字段类具有不同的构造函数,我想不出使用反射或泛型在基础数据访问程序集中创建字段的方法。
我能想到的唯一方法是向每个字段类添加一个“初始化”方法,该方法将包含该特定字段的属性,并在自定义数据类构造函数中执行以下操作:
public CustomerDataClass(StoreDataModel model) : base(model)
{
FirstNameField = AddField<StringField>(this, "FirstName", true, null)
.Initialize(50);
LastNameField = AddField<StringField>(this, "LastName", true, null)
.Initialize(50);
...
}
这将允许我将字段构造函数更改为内部并且不允许任何人创建字段的实例。这个解决方案的问题是它允许任何人运行“Initialize”方法并更改字段(这可以通过添加一个私有布尔成员(m_IsInitialized)来解决,该成员将在“Initialize”第一次运行时设置为true,并且每次调用“Initialize”时,如果m_IsInitialized为真,就会抛出异常,不过这个方案有点丑)。
谁有更好的解决方案?
【问题讨论】:
-
更不用说,如果你在构造函数之外进行初始化,你将失去类不变量的保证,因为你依赖调用者来“帮助”对象构造。但我不是 C# 程序员,所以我真的帮不上忙。 :)
标签: c# inheritance