【问题标题】:Using Attributes for Generic Constraints [duplicate]为通用约束使用属性 [重复]
【发布时间】:2010-11-10 16:32:55
【问题描述】:

举个例子,比如..

public interface IInterface { }

public static void Insert<T>(this IList<T> list, IList<T> items) where T : IInterface
{
 // ... logic
}

这很好用,但我想知道是否可以使用属性作为约束。比如……

class InsertableAttribute : Attribute

public static void Insert<T>(this IList<T> list, IList<T> items) where T : [Insertable]
{
 // ... logic
}

显然这种语法不起作用,否则我不会发布问题。但我只是好奇这是否可能,以及如何做到这一点。

【问题讨论】:

  • 如果实现了我会LOVE...

标签: c# generics attributes extension-methods


【解决方案1】:

不可以。您只能使用(基)类和接口作为约束。

但是你可以这样做:

public static void Insert<T>(this IList<T> list, IList<T> items)
{
    var attributes = typeof(T).GetCustomAttributes(typeof(InsertableAttribute), true);

    if (attributes.Length == 0)
        throw new ArgumentException("T does not have attribute InsertableAttribute");

    /// Logic.
}

【讨论】:

  • 谢谢。这是我的想法,但我认为值得一试。我的项目不需要它,但我认为这是很好的信息。 5 分钟后 Stack Overflow 允许我点击“接受”复选框。
  • 如果您需要该属性进行一些外部处理,而您所控制的界面是标记,那么您可以在界面上声明该属性并选择继承的属性。
  • @Ciel 你无论如何都可以拥有where S : Attribute 然后进行内部运行时验证..
【解决方案2】:

没有。您只能使用类、接口、classstructnew() 和其他类型参数作为约束。

如果 InsertableAttribute 指定 [System.AttributeUsage(Inherited=true)],那么您可以创建一个虚拟类,如:

[InsertableAttribute]
public class HasInsertableAttribute {}

然后像这样限制你的方法:

public static void Insert<T>(this IList<T> list, IList<T> items) where T : HasInsertableAttribute
{
}

那么T 将始终具有该属性,即使它只是来自基类。实现类将能够通过在自身上指定该属性来“覆盖”该属性。

【讨论】:

  • @Jon Skeet 啊,当然。我知道我忘记了什么,感谢您指出!
【解决方案3】:

不,你不能。你的问题不是关于属性,而是面向对象的设计。请阅读以下内容以了解有关generic type constraint 的更多信息。

我宁愿建议您执行以下操作:

public interface IInsertable {
    void Insert();
}

public class Customer : IInsertable {
    public void Insert() {
        // TODO: Place your code for insertion here...
    }
}

因此我们的想法是拥有一个IInsertable 接口,并在您希望可插入时在一个类中实现此接口。这样,您将自动限制可插入元素的插入。

这是一种更灵活的方法,它可以让您轻松地将任何相同或不同的信息从一个实体持久保存到另一个实体,因为您必须在自己的类中实现接口。

【讨论】:

  • 好吧,我根本不需要这样做。它更像是你正在编码的东西之一,它让你觉得这是一个可能对其他东西有用的想法。事实上,如果我需要确保对属性的约束,我会简单地使用一个虚拟类。
  • 我明白你的意思,有时你会想到一些事情并想知道它是否可行。 =) 无论如何,有趣的问题。 =)
猜你喜欢
  • 2011-01-24
  • 1970-01-01
  • 2013-12-27
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多