C#中基类属性值在子类中设置,如何在基类的方法中获取子类设置的值?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#中基类属性值在子类中设置,如何在基类的方法中获取子类设置的值?相关的知识,希望对你有一定的参考价值。

如BaseListForm有Protected属性TableName,子类ListForm继承BaseListForm,在子类中设置TableName为Color,那么在父类的构造函数中如何取得TableName的值?

从设计角度上来说,一般父类不应该访问子类成员,否则这种抽象结构就是没有意义的,当然你也可以访问,直接把this转换成子类类型就可以访问了追问

不是访问子类成员,该成员是父类的,只不过是在子类中赋值,而我想在父类中获取子类所赋的值。

追答

那你直接访问父类的属性就可以获得了,如果你的子类属性是new出来的而不是virtual、abstract或者接口成员,那就是新的属性,只能强制转换来获取

参考技术A 作为子类来说,构造函数ListForm() : base()的调用顺序是先父类后子类。所以子类中设置肯定是滞后的。除非有一个构造函数是带参数的:
BaseListForm(string tableName) this.TableName = tableName;
ListForm(string tableName) : base(tableName) ...
new ListForm("Color");
ps. 从命名规范上来说,ListFormBase要比BaseListForm规范。除非你是BasicListForm。

Rails STI - 防止基类实例化

【中文标题】Rails STI - 防止基类实例化【英文标题】:Rails STI - Prevent base class from instantiation 【发布时间】:2010-05-17 15:31:49 【问题描述】:

在 Rails STI 情况下,当基类被实例化时,有什么方法可以引发错误?覆盖初始化会做到这一点,但随后会渗透到子类。

谢谢

【问题讨论】:

【参考方案1】:

John Topley 的回答实际上是错误的。在基类中设置 abstract_class= true 实际上会导致子类停止自动设置它们的类型。另外,除非你在基类中设置_table_name,否则子类会抱怨他们的表不存在。

这是因为 abstract_class=true 的目的是在您不使用 STI 并希望在 ActiveRecord::Base 和一个或多个模型类。

初始化 raise 是一种解决方案,将 validates_presence_of :type 添加到基类也是一种解决方案。

注意如果你重写了初始化,你需要调用 super:

def initialize(*args)
  raise "Cannot directly instantiate an AbstractUser" if self.class == AbstractUser
  super
end

【讨论】:

【参考方案2】:

你可以试试这个:

class BaseClass
  def initialize
    raise "BaseClass cannot be initialized" if self.class == BaseClass
  end
end

class ChildClass
end

结果将是:

a = BaseClass.new  # Runtime Error
b = ChildClass.new # Ok

希望有帮助

【讨论】:

由于 BaseClass 可能会从 ActiveRecord::Base 继承,所以 initialize 可能应该调用 super。【参考方案3】:

我通常更喜欢简单地将 new 类方法设为私有:

class Base
  private_class_method :new 
end

这种方式意外实例化 Base 类会触发错误,但仍然可以使用 Base.send(:new) 实例化它来为 Base 类编写测试。

【讨论】:

【参考方案4】:

比验证存在性更好的是根据已接受的非抽象类类型的已知列表进行验证

  validates :type, :inclusion=>  :in => ["A", "B", "C"] 

因为如果您只是为了存在而进行验证,“邪恶的开发者”仍然可以将抽象类名作为类型参数传递。

【讨论】:

【参考方案5】:

在初始化函数中检查该类是 STI 基类。

虽然问题是您为什么要这样做?尝试不同的设计似乎更有可能对您有更多帮助。

【讨论】:

【参考方案6】:

您可以在基类中使用self.abstract_class = true 告诉 ActiveRecord 它是一个抽象类。

【讨论】:

以上是关于C#中基类属性值在子类中设置,如何在基类的方法中获取子类设置的值?的主要内容,如果未能解决你的问题,请参考以下文章

派生类(构造函数)中基类的成员变量初始化顺序

C# 隐藏方法和重写方法

Rails STI - 防止基类实例化

c#如何重写类?

关于Java中基类构造器的调用问题

继承和多态