我在课堂上使用initiazling属性 我想在完全初始化后运行验证方法。 由于显而易见的原因,我无法使用构造函数。有没有办法在某种类初始化事件中做到这一点?
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 ...
}
}
答案 0 :(得分:2)
(注意:为了清楚起见,我将属性重命名为Bar,以便轻松将其与Foo类型区分开来)
如果Bar
属性在构造时必须有效,为什么不在构造函数中要求它?你为什么要允许构造无效的对象?
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
}
}
或者,如果您可以构造Foo
的实例而不包含Bar
属性的值,但您不希望允许将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
}
}
答案 1 :(得分:0)
一种方法是为验证目的而设计的界面;例如IValidation
。然后,IValidation
可以包含Validate
方法。需要提供行为的类现在可以以可管理的方式执行此操作。
这可以防止构造函数中的膨胀,这是拙劣的设计。
答案 2 :(得分:0)
您可以避免使用proprty初始值设定项,只需将所有代码移动到构造函数中,如果有很多属性,则使用可选参数。这样,您将获得一种属性初始化器构造函数,但仍然能够在初始化完成后验证该类。像这样:
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");
缺点是这是相对较新的C#4语法。
如果您不能使用c#4,则可以使用属性访问器来启用验证,例如像:
public string Foo
{
get { return foo; }
set
{
foo = value;
Validation();
}
}
但是这将评估每个集合的有效性,如果您一次设置很多属性,可能会很慢。您还可以使用get
访问器与一些延迟加载组合,如下所示:
public bool IsValid
{
get
{
if (!isValidated)
Validation();
return isValid;
}
private set { isValid = value; }
}
public string Foo
{
get { return foo; }
set
{
foo = value;
isValidated := false;
}
}
答案 3 :(得分:0)
您可以向属性添加验证逻辑。验证在分配属性后是否初始化类,如果初始化完成,则引发静态事件。您可以通过将事件发送者强制转换为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;
...
};
答案 4 :(得分:0)
您可以像postsharp一样使用面向方面编程。 http://www.postsharp.org/。但是你会失去表现。