Reputation: 2242
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
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
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
Reputation: 455
You can use Aspect Oriented Programming like postsharp. http://www.postsharp.org/. But you lose on performance.
Upvotes: 0
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
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