2011-02-10 123 views
4

我在类 中使用初始化属性,我想完整初始化后运行验证方法。 我不能使用构造函数的原因很明显。有没有办法在某种类初始化事件中做到这一点?完全初始化类

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

我认为构造函数被调用,虽然你不想要 – 2011-02-10 15:33:19

回答

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; 
    ... 
}; 
0

一种方法是设计用于验证目的的接口;例如IValidation。然后IValidation可以包含一个Validate方法。需要提供行为的类现在可以以可管理的方式进行。

这可以防止在恕我直言是坏设计的构造函数内膨胀。

2

(注:为清楚起见,我改名的属性栏,以方便地从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为无效值,你可以在二传手验证这一点:

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 
    } 
} 
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; 
    } 
}