C# 强制子类在C中定义额外字段#

C# 强制子类在C中定义额外字段#,c#,reflection,C#,Reflection,我的公司有一个基本数据库模型类,它由我们产品的特定实例子类化。该类表示数据库中的主键。基类有一个字段,我们称之为AlwaysPresent,该字段对于产品的所有实例都是通用的,不用于查询 abstract class BaseClass { private string AlwaysPresent } 但要求子类至少再添加一个字段,因为我们稍后将使用反射将这些其他字段作为查询的数据库列名。如果没有其他字段,则无法查询 那么,我的问题是:是否可以使用C#的反射功能强制非抽象子类定义新字段

我的公司有一个基本数据库模型类,它由我们产品的特定实例子类化。该类表示数据库中的主键。基类有一个字段,我们称之为AlwaysPresent,该字段对于产品的所有实例都是通用的,不用于查询

abstract class BaseClass
{
    private string AlwaysPresent
}
但要求子类至少再添加一个字段,因为我们稍后将使用反射将这些其他字段作为查询的数据库列名。如果没有其他字段,则无法查询

那么,我的问题是:是否可以使用C#的反射功能强制非抽象子类定义新字段而不指定其名称


我是一名Python程序员,我确切地知道如何使用元类在Python中解决这类问题。据我所知,C#没有元类。我不能在基类构造函数中引发一个异常,因为(出于各种原因)我们没有为这些类使用构造函数(只是初始化),即使我们这样做了,基类构造函数也可以被重写。

反射不能用于强制执行某些操作。至少在编译时不是这样。通过反射,你可以了解一种类型是怎样的。在您的情况下,您可能可以检查它的字段,并在运行时抛出异常(如果需要)

在任何情况下,通常最好使用属性而不是字段。属性更具可扩展性,更好地隐藏类的内部结构

强制类的特定设计(属性或方法定义)的常用方法是使用接口。您还可以拥有一个实现多个接口的类

如果在设计接口时不知道属性名称或字段,则不能在编译时强制要求,而只能在运行时强制要求


另一种常见的c#技术是用属性装饰属性或字段。也许您可以创建一个自定义属性,并在运行时检查具有该属性的字段(始终带有反射)。

这可以通过Aspect,特别是PostSharp来完成。它允许您在编译期间在CompileTimeValidate中执行自定义代码(事实上,它钩住了postcompile操作):


当然,您可以在生成时用postcompile上触发的任何自定义代码替换PostSharp。

您知道您可以定义抽象属性吗?您可以将其实现为自动属性?@jdv jandavan没有定义这些属性的名称。您可以在运行时使用反射检查这一点,但在编译时无法进行检查。您所说的基类构造函数是什么意思。?无法重写构造函数。没有问题。你现在知道了。构造函数和析构函数永远不能被重写。这样做会有所帮助,但会影响性能,因为反射非常慢。如果符合您的要求,您也可以将抽象属性添加到基类中。我将用我从动态语言世界中理解的术语解释它;也许这会让事情变得更清楚。在Python中,我可以在类创建中添加一个钩子,以便在类定义时,Python解释器将使用反射来检查字段,然后,如果这些字段不符合我的喜好,我的钩子将引发一个异常。@很抱歉,但C#不是Python,您不能这样做。强制执行这些类型的契约的正确方法是拥有期望类实现的接口。@MLE:由于C#不是像Python那样的动态语言,因此类的创建是在编译时进行管理的,而不像Lisp这样的语言,目前还没有办法钩住这部分过程。您只能在运行时强制执行这些约束,并彻底测试代码,以确保没有违反这些约束的内容。@ScottChamberlain再次强调,我不能使用接口,因为我无法预先知道字段名称。所以,如果答案是“不,那是不可能的”或者“不,那是不可能的,除非遵循一定的条件”,这是我能要求的最好的答案。如果你编辑你的答案,我会接受。我已经编辑了答案。检查您的情况是否更清楚。