我的公司有一个基础数据库模型类,它由我们产品的特定实例子类化。 该类表示数据库中的主键。 基类有一个字段,我们称之为AlwaysPresent,它对产品的所有实例都是通用的,不用于查询。
abstract class BaseClass { private string AlwaysPresent }但是要求子类至少添加一个字段,因为我们稍后会使用反射将这些其他字段视为查询的数据库列名。 如果没有其他字段,我们无法查询。
所以,我的问题是:是否可以使用C#的反射功能强制非抽象子类定义新字段而不指定其名称?
我是一名Python程序员,我知道如何使用元类在Python中解决这类问题。 据我所知,C#没有元类。 我不能在基类构造函数中引发异常,因为(由于各种原因)我们不为这些类(只是初始化器)使用构造函数,即使我们做了基类构造函数也可以被覆盖。
My company has a base database model class that is subclassed by particular instances of our product. The class represents primary keys in a database. The base class has a field, which we'll call AlwaysPresent, which is common to all instances of the product and is not used in querying.
abstract class BaseClass { private string AlwaysPresent }But it is a requirement that subclasses add at least one more field, as we will use reflection later to treat those other fields as database column names for a query. If there are no other fields, we can't query.
So, my question: is it possible to use C#'s reflection capabilities to force a non-abstract subclass to define new fields without specifying their names?
I am a Python programmer by trade, and I know exactly how to solve this kind of problem in Python using metaclasses. To my knowledge, C# does not have metaclasses. And I cannot raise an exception in the base class constructor, because (for various reasons) we don't use constructors for these classes (just initializers), and even if we did the base class constructor could be overridden.
最满意答案
反射不能用来逼迫某事。 至少不是在编译时。 通过反射,您可以阅读类型。 在您的情况下,您可以检查其字段并在运行时根据需要抛出异常。
在任何情况下,通常使用属性而不是字段要好得多。 属性更具可扩展性,更好地隐藏类的内部结构。
实现类的特定设计(属性或方法定义)的常用方法是使用接口。您还可以拥有一个实现多个接口的类。
如果在设计接口时不知道属性名称或字段,则无法在编译时强制执行您的要求,而只能在运行时强制执行。
另一种常见的c#技术是用属性装饰属性或字段。 也许您可以创建自定义属性,并在运行时检查具有该属性的字段(始终使用反射)。
Reflection cannot be used to force something. At least not at compile time. Via reflection you can read how a type is. In your case you can probably check its fields and throw an exception if required at run time.
In any case usually it is much better to use properties instead of fields. Properties are more extensible and better to hide the internal structure of a class.
A common way to enforce a specific design (properties or methods definition) of a class is to use interfaces.You can have also a class that implement more than one interface.
If properties names or fields are not know when designing the interface you cannot enforce your requirements at compile time but only at run time.
Another common c# technique is to decorate properties or fields with attributes. Maybe you can create a custom attribute and at run time check for fields with that attribute (always with reflection).
更多推荐
发布评论