【问题标题】:Overwriting abstract method in partial class覆盖部分类中的抽象方法
【发布时间】:2012-04-12 11:27:41
【问题描述】:

我有一个名为PersonAbstract 的抽象类。它有一个抽象属性,叫做Age

abstract public int Age { get; set; }

两个名为CustomerEmployee 的类扩展PersonAbstract

CustomerEmployee 是使用 Linq-to-SQL 创建的,因此它们具有自动生成的代码。

这两个的自动生成代码:

public int Age
{
   get
   {
      return this._age;
   }
   set
   {
      this._age = value;
   }
}

我使用部分类向EmployeeCustomer 添加功能。

public partial class Employee: PersonAbstract
{
.....

如何更改此结构,以便继承类(EmployeeCustomer)的 person 属性覆盖抽象类中的 person 属性而不触及自动生成的代码?

编辑:

问题是我想让两个类共享一些父类的代码。因此,我一直在尝试在具有Age 属性的实现接口和两个子类之间添加具有共享代码的抽象类。但是该代码需要访问Age 属性。所以抽象类必须使用Age 属性的抽象实例来实现接口,并且子类会覆盖它。如果这是不可能的,我还能如何达到预期的结果?

【问题讨论】:

    标签: c# inheritance abstract-class partial-classes auto-generate


    【解决方案1】:

    您不能 - 自动生成的代码没有使用 override,因此它不能覆盖现有成员。

    如果您将年龄属性放入接口,那么自动生成的代码会很乐意为您实现该接口。

    【讨论】:

    • 谢谢,它实际上已经在一个界面中。问题是我想让两个类共享一些父类的代码。所以我一直在尝试在接口和两个子类之间添加抽象类。但是该代码需要访问 Age 属性。所以抽象类必须使用 Age 属性的抽象实例来实现接口,并且子类会覆盖它。我还能如何实现这一目标?
    • @user277498:这很可怕,但是当您需要使用其成员时,您可以将抽象类 cast this 设置为接口类型,然后将其部分类派生自抽象类并实现接口。构造函数可以检查this 是否真的实现了接口,如果没有则抛出异常。感觉应该有更好的方法...您是否探索了设计器中的所有选项,以告知代码生成器有关基类并添加覆盖?
    • 是的,对于每个属性,设计师都有一个可以设置为覆盖的 InheritanceModifier。这似乎奏效了。谢谢!
    • @user277498:那就这样吧,是的。比带有强制转换的界面版本要好得多。
    • 从 C# 版本 9 开始,这现在是可能的!当它没有在非分部类中抽象时会产生编译器错误,而当它没有在任何分部类中实现时会产生错误。
    【解决方案2】:

    我想扩展我对 Jon Skeet 回答的评论。从 C# 9 开始,the rules for partial methods have been relaxed 因为引入了source generators。这是我的用例。我有一个声明为 abstract 的方法,我想通过源代码生成器来实现它,因为编写起来非常重复。

    public class DomainEvent
    {
        public int Version;
    }
    
    public abstract class Aggregate
    {
        public abstract string Id { get; }
        
        // This is the method I want to automatically generate through a source generator
        protected abstract void Route(DomainEvent @event);
    }
    
    
    public partial class Inventory : Aggregate
    {
        public override string Id => "42";
    }
    
    public partial class Inventory 
    {
        protected override void Route(DomainEvent @event)
        {
            // Do something
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-02
      • 1970-01-01
      • 2014-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多