我有一个包含Products的数据库。这些产品已分类,具有类别和子类别。
例如:
Product p1 = new Product()
{
Category = Category.Fruit,
Subcategory = Subcategory.Apple
};
Run Code Online (Sandbox Code Playgroud)
我的问题是我想根据类别限制子类别。
下面的示例应该是不可能的:
Product p2 = new Product()
{
Category = Category.Fruit,
Subcategory = Subcategory.Cheese
};
Run Code Online (Sandbox Code Playgroud)
此外,我希望能够返回一个字符串数组(匹配每个Category枚举),每个字符串都有一个对应子类别的数组。
我已经思考了一段时间,但没有提出任何建议,也没有在线找到任何解决方案。
有什么建议?
我喜欢地图规则。您还可以在枚举值上放置自定义属性。
例如:
public enum Subcategory {
[SubcategoryOf(Category.Fruit)]
Apple,
[SubcategoryOf(Category.Dairy)]
Emmenthaler
}
Run Code Online (Sandbox Code Playgroud)
这要求您编写一个SubcategoryOfAttribute类(有关MS指南,请参见此处)。然后,您可以编写一个验证程序,该验证程序可以查看任何子类别并从中获取合法的父类别。
相对于地图而言,这样做的优势在于,在声明中很好地阐明了关系。
缺点是每个子类别最多只能有一个父类别。
我对此很感兴趣,因此我将其存根。首先是属性:
[AttributeUsage(AttributeTargets.Field)]
public class SubcategoryOf : Attribute {
public SubcategoryOf(Category cat) {
Category = cat;
}
public Category Category { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我们做一些模拟枚举
public enum Category {
Fruit,
Dairy,
Vegetable,
Electronics
}
public enum Subcategory {
[SubcategoryOf(Category.Fruit)]
Apple,
[SubcategoryOf(Category.Dairy)]
Buttermilk,
[SubcategoryOf(Category.Dairy)]
Emmenthaler,
[SubcategoryOf(Category.Fruit)]
Orange,
[SubcategoryOf(Category.Electronics)]
Mp3Player
}
Run Code Online (Sandbox Code Playgroud)
现在我们需要一个谓词来确定子类别是否与类别匹配(注意:如果需要,您可以具有多个父类别-您需要修改属性和该谓词以获取所有属性并检查每个属性。
public static class Extensions {
public static bool IsSubcategoryOf(this Subcategory sub, Category cat) {
Type t = typeof(Subcategory);
MemberInfo mi = t.GetMember(sub.ToString()).FirstOrDefault(m => m.GetCustomAttribute(typeof(SubcategoryOf)) != null);
if (mi == null) throw new ArgumentException("Subcategory " + sub + " has no category.");
SubcategoryOf subAttr = (SubcategoryOf)mi.GetCustomAttribute(typeof(SubcategoryOf));
return subAttr.Category == cat;
}
}
Run Code Online (Sandbox Code Playgroud)
然后输入产品类型进行测试:
public class Product {
public Product(Category cat, Subcategory sub) {
if (!sub.IsSubcategoryOf(cat)) throw new ArgumentException(
String.Format("{0} is not a sub category of {1}.", sub, cat), "sub");
Category = cat;
Subcategory = sub;
}
public Category Category { get; private set; }
public Subcategory Subcategory { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
测试代码:
Product p = new Product(Category.Electronics, Subcategory.Mp3Player); // succeeds
Product q = new Product(Category.Dairy, Subcategory.Apple); // throws an exception
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2208 次 |
| 最近记录: |