C# 属性重写 Set 方法

4

我有一个类如下所示,当某人设置值时,我想覆盖“School,Country等”属性的设置值。 我不想更改学生类,但我需要在基类中执行此操作并将其用作通用方法。

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

例如:当有人设置Student.School="Harvard"时,我需要将其存储为Student.School="Harvard my custom value"

注意:基本上在基类中调用OnPropertyChanged而不是主类。

5个回答

1
如果你想使用方面来实现它,那么可以尝试 Postsharp

我认为那不是免费的,我需要购买它 :-) - kayak

0

基本上你不能覆盖一个非虚拟属性。你可以在派生类中使用同名的其他属性来隐藏它,但是如果一些其他代码通过对基类的引用访问你的对象,这不会给你想要的效果。


可以使用面向方面编程模型,例如 [MyCustomAttribute] public String School{get;set;}; 来实现吗? - kayak
不确定,但如果是的话,这肯定需要在“BaseClass”的一侧编写一些代码。 - Vlad
是的,我同意,在基类上需要做一些工作。但是如何做呢..? - kayak
如果您可以修改基类,会出现什么问题? - Vlad
我还没有修改基类,正在寻找修改它的方法。 - kayak

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

你的意思是这样吗?

如果School属性在BaseClass中,那么你可以使用new关键字,或者如果你控制BaseClass,那么你可以在School属性上添加virtual关键字,并在Student类中进行override


但我不想在Student类中这样做,我想在BaseClass中实现,因为我有数百个属性在几个类中..我想将公共值附加到其末尾。 - kayak
在基类中实现它,我不明白你在这里的问题是什么。你想要能够更改该值吗?使用事件或委托,或者在BaseClass的属性设置器上调用虚函数,然后在Student类中重写它。 - bevacqua
我的意思是,我不想写每个属性的 set 方法,因为这太麻烦了。不过我需要找到一种自动化的方式来实现它。例如,如果属性值为“Harvard”,则将其更改为“Harvard custom”。 - kayak
考虑自定义值是时间(分钟和秒)...我不想在每个属性上编写代码。 - kayak
你想在类的每个属性上添加类似最后修改日期的东西吗? - bevacqua
最初我想在每个属性设置值时调用"OnPropertyChanged"方法,而不必在每个属性中编写它(但如果将其作为属性,则可以接受)。 - kayak

0

仅通过修改BaseClass是不可行的。这样想:如果能够如此轻松地“注释”自动属性,那么我们就不需要为实现INotifyPropertyChanged(同样适用于DependencyProperties)的数据模型类编写所有那些<rant>无用的大量</rant>手动属性实现。

您需要在子类中提供钩子,以供基类使用。实现PropertyChanged(您已经提到了),是一种可能的解决方案,另一种解决方案是简单的方法调用:

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

如果你有很多需要这个的子类,你可以使用Visual Studio Code Snippets来创建代码或者T4模板


0

由于您的基类没有这些属性,因此您将无法使用标准OOD模式或原则从基类内部修改它们。

现在,如果您将属性作为普通属性或虚拟属性移动到基类中,则可以修改属性的set块中所做的工作以执行额外的操作。

但是,如果您无法将它们移动到基类中,并且您无法修改Student类,就像您在问题中暗示的那样,那么您可以将学生类封装在一个新类(例如StudentProxy)中,然后让它公开类似的属性,然后调用真正的学生类以实现您想要的效果。

例如:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接