完全初始化的课程

时间:2011-02-10 15:28:40

标签: c# constructor initialization

我在课堂上使用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 ...
   }

}

5 个答案:

答案 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/。但是你会失去表现。