2012-01-04 43 views
36

根據標題,是否可以在c#4中聲明類型 - 否定約束?generic NOT constraint where T:!IEnumerable

+6

即使有,你可以描述一個用例? – 2012-01-04 13:18:06

+1

觀察你有這樣的要求是很奇怪的。您只能針對您認爲屬於班級家庭的類型T進行編碼。你怎麼能用泛型編碼呢?要麼在這種情況下不需要泛型,要麼需要修改用例。 – 2012-01-04 13:46:43

+2

感興趣的用例是允許以下重載並存:void void doIt (T what){} void doIt (IEnumerable whats){} - 目前存在歧義,因爲'T '在第一個方法可能是'IEnumerable <>'(所以我想指定'T'不應該是'IEnumerable')... – Cel 2012-01-04 14:14:22

回答

36

不 - 在C#或CLR中都沒有這樣的概念。

+0

這個概念將來會用於C#和/或CLR嗎? – 2015-07-16 14:25:05

+0

@RandRandom:我還沒有聽說過任何計劃。 – 2015-07-16 14:25:47

0

沒有,但它是可以檢查與「是」,然後處理它適當地...

1

您使用的約束,這樣可以保證你使用的類型有一定的屬性/方法/ .. 你想用

帶類型否定約束的泛型沒有任何意義,因爲沒有任何目的可以知道不想使用某些屬性/方法

+0

顯然你還沒有收到錯誤:##''不能實現'>'和'>',因爲它們可能統一了一些類型參數替換##。 。當然有些情況下,當你想指定genericstype2不能是generictype4 – 2014-10-03 21:26:42

+0

我可以通過使用一系列實現類似接口實例的抽象類來解決我的場景,並繼承抽象類..我想那就是Action 等等。 – 2014-10-03 21:39:56

4

據我所知,這是不可能的。

你可以做的是一些運行時檢查:

public bool MyGenericMethod<T>() 
{ 
    // if (T is IEnumerable) // don't do this 

    if (typeof(T).GetInterface("IEnumerable") == null) 
     return false; 

    // ... 

    return true; 
} 
+1

你不能像'那樣使用' - 它測試一個* object *是否與一個類型兼容。 – 2012-01-04 13:32:27

+2

你的意思是if(typeof(T)== typeof(IEnumerable)){}' – kev 2012-01-04 13:53:43

0

一個使用了這將是一個選項類型。

public class Option<A,B> 
where A : !B 
where B : !A 
{ 
    private readonly A a; 
    private readonly B b; 

    private Option(){} 

    public Option(A a) 
    { 
     this.a = a 
    } 

    public Option(B b) 
    { 
     this.b = b 
    } 
} 

運行時檢查當然會起作用,但是在編譯時你沒有類型檢查的好處。

2

我發現我自己想實現在評論中提到的相同的情況下

void doIt<T>(IEnumerable<T> what) { } 
void doIt<T>(T whats) { } 

除外下面的代碼來引用第一種方法

doIt(new List<T>()); 

但它實際上引用第二個

一種解決方案是的說法是這樣的:

doIt(new List<T>().AsEnumerable<T>()); 

演員可以通過另一個重載隱藏:

void doIt<T>(List<T> whats) { 
    doIt(whats.AsEnumerable<T>()); 
} 
相關問題