开发者

Is there a way to intercept setters and getters in C#?

In both Ruby and PHP (and I guess other languages as well) there are some utility methods that are called whenever a property is set. ( *instance_variable_set* for Ruby, *__set* for PHP).

So, let's say I have a C# class like this:

public class Person
{
    public string FirstName { get; set; }开发者_运维问答
    public string LastName { get; set; }
}

Now, let's say that if any property setter from the Person class is called, I want to call another method first, and then continue with the default behaviour of the setter, and the same applies for the property setters.

Is this possible?


Edit: I want to do this without defining a backing field.


Not generally; a few options though;

  • inherit from ContextBoundObject - which does allow this, but at a performance cost
  • write an explicit property (i.e. with a backing field), and add a utility method call manually
  • look at compile-time weavers, such as PostSharp - generally by spotting an attribute or similar
  • look at runtime code generators, as offered by some DI/IoC tools (and some other "decorator" based tools) - which either decorate or subclass your object to add the extra code


It is possible to do directly in the property body itself, but then you need to use a proper backing field instead of auto-implemented properties.

private string firstName;

public string FirstName 
{ 
  get { return firstName;} 
  set 
  {
    if(check(value))
    {
       firstName = value;
    }
  } 
}

Even with auto-implemented properties you get a backing field - this is generated by the compiler and you don't have direct access to it.


Edit:

Seeing as you don't want a backing field, you have other options - using an AOP tool such as PostSharp could help with that.


You will have to write the properties in full to achieve this.


I know this has been properly answered but I'll include an example to show you the syntax to achieve what you want:

public class Person
{
    private 
    public string FirstName
    {
        get
        {
            return _firstName;
        }
        set
        {
            // see how we can call a method below? or any code for that matter..
            _firstName = SanitizeName(value);
        }
    }
}


Are you in a position to rewrite your class to implement an interface? If so, Unity's interface interceptor might give you what you need. If an interface is not an option then that link also documents Unity's type and instance interceptors.


Not out of the box. You would need to insert code into each properties setter and getter, either manually or automatically using IL rewriting.

When you want to do it manually, you can't use automatic properties any more.
When you want to do it automatically, have a look at AOP.


Yes, of course...

In your example you are using automatic properties, without a backing field.... You just need to create a backing field for your property, and then you can do what you want in the setter and getter.

example:

private string firstName;

public string FirstName
{
 get { return firstName; }

 set { doMethod(); firstName = value;}
}


Mocking frameworks can do this, as well as IoC libraries like Unity. The only other way to do such a thing would be to use IL-rewriting (as previously mentioned).


You cant use automatic properties. You would have to dinfe the property out the old fashion way with a backing field and call the method manually.

public class Person
{
    private string _FirstName;
    public string FirstName 
    { 
        get
        {
            return _FirstName;
        }
        set
        {
            SomeMethod();
            _FirstName = value;
        }
    }
    private void SomeMethod()
    {
        //do something
    }

}


As far as I know, you have to use a backing field and put the call to the other method inside the setter thusly:

public class Person {
    private string firstName;
    private string lastName;

    public string FirstName {
        set { 
            DoSomeStuff();
            firstName = value;
        }
        get { return firstName; }
    }

    public string LastName { 
        set {
            DoSomeStuff();
            lastName = value;
        }
        get { return lastName; }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜