C# 完全初始化类
我在类中使用initiazling属性 我想在完全初始化后运行一个验证方法。 我不能使用构造函数,原因很明显。有没有一种方法可以在类初始化事件中实现这一点C# 完全初始化类,c#,constructor,initialization,C#,Constructor,Initialization,我在类中使用initiazling属性 我想在完全初始化后运行一个验证方法。 我不能使用构造函数,原因很明显。有没有一种方法可以在类初始化事件中实现这一点 var t = new Foo { foo = ""; } class Foo { public string foo {get; set;} ... public bool validate {get ; set;} priv
var t = new Foo
{
foo = "";
}
class Foo
{
public string foo {get; set;}
...
public bool validate {get ; set;}
private void validation()
{
if(foo == "")
validate = false;
if ...
}
}
一种方法是为验证目的而设计的接口<例如,代码>IValidation<代码>验证然后可以包含一个
验证
方法。需要提供行为的类现在可以以可管理的方式提供行为
这可以防止构造函数中的膨胀,因为IMHO是糟糕的设计。(注意:为了清楚起见,我将属性重命名为Bar,以便轻松将其与Foo类型区分开来)
如果条
属性在构造时必须有效,为什么不在构造函数中要求它?为什么允许构造无效对象
class Foo
{
public Foo(string bar) {
if(!IsValidBar(bar))
throw new ArgumentException("bar is not valid.", "bar");
this.Bar = bar;
}
public string Bar {get; set;}
private bool IsValidBar(string bar)
{
// blah blah
}
}
或者,如果您可以在不使用Bar
属性值的情况下构造Foo
的实例,但不允许将Bar
设置为无效值,则可以在setter中验证这一点:
class Foo
{
private string bar;
public string Bar
{
get { return bar; }
set
{
if(!IsValidBar(value))
throw new ArgumentException("bar is not valid.", "value");
bar = value;
}
}
private bool IsValidBar(string bar)
{
// blah blah
}
}
您可以避免使用属性初始值设定项,只需将所有代码移动到构造函数中,如果有很多属性,则使用可选参数。这样,您将获得某种属性初始值设定项构造函数,但在初始化完成后仍然能够验证该类。大概是这样的:
class Foo
{
public string Foo {get; set;}
public string Bar {get; set;}
public bool IsValid {get ; set;}
private void Validation()
{
if(foo == "")
IsValid = false;
if ...
}
public void Foo(string foo = string.Empty, string bar = string.Empty)
{
Foo = foo;
Bar = bar;
Validation();
}
}
.....
var t = new Foo (Foo = "SomeString");
public bool IsValid
{
get
{
if (!isValidated)
Validation();
return isValid;
}
private set { isValid = value; }
}
public string Foo
{
get { return foo; }
set
{
foo = value;
isValidated := false;
}
}
缺点是这是一种相对较新的C#4语法
如果不能使用c#4,可以使用属性访问器启用验证,例如:
public string Foo
{
get { return foo; }
set
{
foo = value;
Validation();
}
}
但是,这将评估每个集合的有效性,如果同时设置许多属性,可能会很慢。您还可以将get
访问器与一些延迟加载结合使用,如下所示:
class Foo
{
public string Foo {get; set;}
public string Bar {get; set;}
public bool IsValid {get ; set;}
private void Validation()
{
if(foo == "")
IsValid = false;
if ...
}
public void Foo(string foo = string.Empty, string bar = string.Empty)
{
Foo = foo;
Bar = bar;
Validation();
}
}
.....
var t = new Foo (Foo = "SomeString");
public bool IsValid
{
get
{
if (!isValidated)
Validation();
return isValid;
}
private set { isValid = value; }
}
public string Foo
{
get { return foo; }
set
{
foo = value;
isValidated := false;
}
}
您可以向属性添加验证逻辑。验证类是否在分配属性后初始化,并在初始化完成时引发静态事件。您可以通过将事件发送器强制转换为Foo来获取对实例的引用
public string Foo
{ get { return _foo; }
set
{
_foo = value;
if (IsInitialized)
OnClassInitialized();
}
}
public static event EventHandler ClassInitialized;
private OnClassInitialized()
{
if (ClassInitialized != null)
ClassInitialized(this, EventArgs.Empty);
}
用法:
Foo.ClassInitialized += (sender, e) =>
{
Foo foo = sender as Foo;
...
};
您可以使用面向方面的编程,如postsharp。但是你会失去性能。我认为构造函数被调用了,尽管你不想我不知道你不能在构造函数中这样做的明显原因。你能澄清一下吗?我想这是因为属性初始值设定者…是的,这是因为属性初始值设定者…伙计们。这是一个复杂的问题,甚至是更复杂的答案。我不想使用构造函数,因为初始化器是更漂亮的代码。也许这是值得考虑的。我可能会使用C'tor和参数。谢谢