guyl
guyl

Reputation: 2242

fully initialized class

I am using initiazling property in a class and i want to run a validation method after it fully initialized. i cant use the constructor for obvious reasons. is there a way to do that in some kind of Class initialized event ?

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

}

Upvotes: 4

Views: 297

Answers (5)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236188

You can add verification logic to properties. Verify if class initialized after property assigned and raise static event if initialization completed. You can get reference to instance by casting event sender to 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);
} 

Usage:

Foo.ClassInitialized += (sender, e) => 
{ 
  Foo foo = sender as Foo;  
  ...
};

Upvotes: 0

SWeko
SWeko

Reputation: 30872

You can avoid using proprty initializers, and just move all that code to the constructor, using optional parameters if there are lots of properties. That way, you'll get kind-of property initializer constructor, and yet still be able to validate the class after the initialization is done. Something like this:

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");

The downside is that this is relatively new C# 4 syntax.

If you can't use c# 4, you could use the property accessors to enable validation, e.g. like:

public string Foo
{
  get { return foo; }
  set 
  {
    foo = value;         
    Validation();
  }
}

but this will evaluate the validity on each set, and might be slow if you set a lot of properties at once. You could also use the get accessor on combination with some lazy loading, something like this:

public bool IsValid
{
  get 
  { 
    if (!isValidated)
       Validation();
    return isValid;
  }
  private set { isValid = value; }
}

public string Foo
{
  get { return foo; }
  set 
  {
    foo = value;         
    isValidated := false;
  }
}

Upvotes: 0

Burcephal
Burcephal

Reputation: 455

You can use Aspect Oriented Programming like postsharp. http://www.postsharp.org/. But you lose on performance.

Upvotes: 0

R. Martinho Fernandes
R. Martinho Fernandes

Reputation: 234354

(Note: for clarity, I renamed the property to Bar, in order to easily distinguish it from the type Foo)

If the Bar property must be valid upon construction, why are you not requiring it in the constructor? Why are you allowing the construction of invalid objects?

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

Alternatively, if you can construct an instance of Foo without the value of the Bar property, but you don't want to allow setting Bar to an invalid value, you can validate this in the 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
    }
}

Upvotes: 2

Aaron McIver
Aaron McIver

Reputation: 24713

One approach is an interface designed for validation purposes; IValidation for instance. IValidation could then contain a Validate method. Classes which need to provide the behavior can now do so in a manageable way.

This prevents bloating within the constructor which IMHO is bad design.

Upvotes: 0

Related Questions