2010-11-10 58 views
12

给出的例子如..使用属性的泛型约束

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 
} 

显然这种语法不起作用,或者我不会发布问题。但我只是好奇,如果可能或不可以,以及如何去做。

+2

我会* LOVE *如果这是实现... – tenfour 2013-02-09 16:57:39

回答

11

只能使用(碱)类和接口的约束。

但是,您可以做这样的事情:

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. 
} 
+0

感谢。这是我的想法,但我认为这是值得一试。我的项目不需要它,但我认为这是很好的信息。当Stack Overflow允许我在5分钟内点击'Accept'复选框。 – Ciel 2010-11-10 16:43:04

+0

不客气。 – 2010-11-10 16:54:45

+0

如果您需要用于某些外部处理的属性(您控制的接口是标记),则可以在接口上声明属性并选择继承的属性。 – smartcaveman 2012-05-30 16:24:05

7

号只能使用类,接口,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总是有属性即使是只来自基类。实现类可以通过指定它自己来“覆盖”该属性。

+0

和其他类型参数:) – 2010-11-10 16:40:16

+0

@Jon Skeet当然啊。我知道我忘记了一些东西,谢谢指出! – 2010-11-10 16:45:05

-1

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

我宁愿建议你做到以下几点:

public interface IInsertable { 
    void Insert(); 
} 

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

这样的想法是有一个IInsertable接口,每当你想插入一个类中实现了这个接口。这样,您将自动限制插入元素的插入。

这是一个更灵活的方法,并应给你轻松从实体坚持什么相同或不同的信息到另一个,因为你要实现你的类中自己的接口。

+0

好了,我不需要做的。它更像是你编写代码的东西之一,它会让你成为一个可能对别的东西有用的想法。事实上,如果我需要确保对Attribute的约束,我会简单地使用一个虚拟类。 – Ciel 2010-11-10 17:00:07

+0

我明白了你的观点,并且有时候你会想到某件事,并想知道它是否可行。无论如何,=)有趣的问题。 =) – 2010-11-11 14:59:03