我们有一个BaseClass和一组派生的 POCO 类(参见 参考资料DerivedClassA)。它们映射到数据库中我们目前无法更改的现有键值存储。
派生类上的每个属性都将映射到存储中的一个键。属性表示的键是字符串值,它们是属性名称或(如果存在)自定义属性MyAttribute.Key,PropertyC如下所示。属性的常见用例是如果键以整数开头,这对于 C# 属性名称无效(并且我们无法更改键)。
public class BaseClass
{
public int BaseClass Id { get; set; } = 0;
}
public class DerivedClassA : BaseClass
{
public int PropertyA { get; set; }
public int PropertyB { get; set; }
[MyAttribute(Key = "404Property")]
public int PropertyC { get; set; }
}
在代码中,我们需要以字符串的形式获取键值。在从其他 SO 答案中进行了一些摔跤和挖掘之后(我不声称对泛型具有任何专业水平),我们想出了下面GetKey()派生的方法BaseClass<T>。请注意,这GetCustomAttributeValue<T>()是一个返回属性值的自定义帮助器方法(可能有更好的方法来做到这一点,但这超出了本问题的范围)。
public class BaseClass<T> : BaseClass where T : BaseClass<T>
{
public string GetKey(Expression<Func<T, object>> property)
{
var memberInfo = GetMemberInfo(property);
return GetAttributeKey(memberInfo) ?? memberInfo?.Name;
}
private static MemberInfo GetMemberInfo(Expression<Func<T, object>> property) =>
(property.Body as MemberExpression ?? ((UnaryExpression)property.Body).Operand as MemberExpression)?.Member;
private static string GetAttributeKey(MemberInfo member) =>
member.GetCustomAttributeValue<string>(typeof(MyAttribute), "Key");
}
如果我们从新的类派生类,这个解决方案似乎有效 BaseClass<T>
public class DerivedClassA : BaseClass<T> {
...
}
在GetKey()现在被称为如下:
var derivedClassA = new DerivedClassA();
var propertyCKey = derivedClassA.GetKey(p => p.PropertyC);
BaseClass然而,我们有一个需要保留的需求,我们不希望BaseClass.
当我尝试GetKey()进入 non-generic 时BaseClass,它不再具有T派生类的类型,它需要在派生类上查找属性集。我不想GetKey()在每个派生类中添加重复的s。
题:
有没有办法将GetKey()方法(可能重写它)移入BaseClass而不是引入新的BaseClass<T>仅用于支持GetKey()?
附加背景:
我们试图将面向对象/强类型包装在一个数据存储周围,该数据存储只是一个看起来像这样的表:
| PreferenceId | UserId | PreferenceString |
每个派生类代表一个不同的PreferenceId. 每个PreferenceString都只是一串以自定义方式“序列化”的键/值PreferenceId(没有可以在所有人之间共享的韵律/原因PreferenceIds)。这一切都应该在某个时候重新设计,但我们正在尝试将当前商店包装在某种强类型中,作为过渡的一个步骤。
慕丝7291255
相关分类