2010-11-10 122 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