полностью инициализированный класс - PullRequest
4 голосов
/ 10 февраля 2011

Я использую свойство initiazling в классе и хочу запустить метод проверки после его полной инициализации.я не могу использовать конструктор по понятным причинам.есть ли способ сделать это в каком-то событии, инициализированном Class?

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 ]

2 голосов
/ 10 февраля 2011

(Примечание: для ясности я переименовал свойство в 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 до недопустимого значения, вы можете проверить это в установщике:

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 голосов
/ 10 февраля 2011

Вы можете использовать Aspect Oriented Programming, как postsharp.http://www.postsharp.org/. Но вы проигрываете по производительности.

0 голосов
/ 10 февраля 2011

Вы можете добавить логику проверки в свойствах. Проверьте, инициализирован ли класс после присвоенного свойства, и вызовите статическое событие, если инициализация завершена. Вы можете получить ссылку на экземпляр, приведя отправителя события к 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 голосов
/ 10 февраля 2011

Вы можете избежать использования инициализаторов 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;
  }
}
0 голосов
/ 10 февраля 2011

Один из подходов - это интерфейс, разработанный для валидации;IValidation например.IValidation может содержать Validate метод.Классы, которые должны обеспечивать поведение, теперь могут делать это управляемым способом.

Это предотвращает вздутие живота внутри конструктора, что, по моему мнению, является плохим дизайном.

...