c# property override Set method

2019-05-07 20:46发布

问题:

I have a class like the below, I want to override the set value of "School,Country..etc.." property when some one sets a value , i don't want to change the student class but i need to do it in the base class and use it as a generic method

public class Student : BaseClass
{
       public String School { get; set; }
       public String Country{ get; set; }
}

ie: When some one sets Student.School="Harvard", I need to store it as
Student.School="Harvard my custom value";

Note: Basically calling OnPropertyChanged in base class rather than the main class.

回答1:

If you want to do it with aspects, then try Postsharp



回答2:

Basically you cannot override a non-virtual property. You can hide it by other property with the same name in the derived class, but this won't give you the desired effect if some other code accesses your object by the reference to the base class.



回答3:

public class Student : BaseClass
{
    private string _school
    public string School 
    {
        get { return _school; }
        set
        {
            if(value == "Harvard")
                value = "Harvard custom";

            _school = value;
        }
    }

    public String Country{ get; set; }
}

is that what you mean?

If the School property is in the BaseClass then you can either use the new keyword, or if you control the BaseClass, then you can add the virtual keyword to the School property there, and override it in the Student class.



回答4:

This is just not doable by solely modifying BaseClass. Think about it this way: If it were possible to "annotate" automatic properties that easily, then we wouldn't need all those <rant>useless tons of</rant> manual property implementations for data model classes that implement INotifyPropertyChanged (same for DependencyProperties).

You need to provide hooks in your subclasses that your base class can use. Implementing PropertyChanged, which you already mentioned, is one possible solution, another one would be a simple method call:

public class Student : BaseClass
{
   private string _school;
   public String School 
   {
       get { return _school; }
       set {
            _school = value;
            DoMoreChanges(ref _school);  // DoMoreChanges is defined in BaseClass
       }
   }

   public String Country{ get; set; }
}

If you have lots of subclasses that need this, you can either use Visual Studio Code Snippets to create the code or T4 templates.



回答5:

Since your base class does not have those properties you will not be able to modify them from within the base class using standard OOD patterns or principles.

Now if you move the properties to your base class either as normal properties or virtual properties you can modify what you do in the set block of the properties to do extra work.

However if you cannot move these to the base class, and you cannot modify the Student class, as you seem to imply in you question, then you could encapsulate the student class within a new class like StudentProxy or something and then have it expose similar properties that will then call into the real student class how you want.

For example:

public class StudentProxy
{
    private Student _student;

    public StudentProxy(Student student)
    {
        this._student = student;
    }

    public String School
    {
        get { return _student.School; }
        set
        {
            _student.School = value + "  my custom value";
        }
    }

    public String Country
    {
        get { return _student.Country; }
        set
        {
            _student.Country = value + "  my custom value";
        }
    }
}


标签: c# reflection