2009-02-18 44 views
4

我想能夠在C#2.0聲明函數作爲採取任何類型的值的數組作爲正式參數

void foo(<any value type>[] data){} 

。如果我聲明爲

void foo(ValueType[] data){} 

它編譯,但隨後就好像它們是從object導出數據[]的元素被處理,例如我不能說像

fixed (void* pData = data){} 

我想避免服用無效*作爲參數 - 我只是希望能夠接受任何值類型的數組,然後做非託管的東西出來。

ETA:此外,這有同樣的問題:

public static unsafe void foo<T>(T[] data) where T:struct{ 
    fixed(void *p = data){} 
} 

的情況下,你不知道。修復失敗,因爲它被視爲託管類型--CS0208,無法聲明指向託管類型的指針。請參閱下面的「mm」。我認爲他是對的......這可能是無法完成的。

+1

大聲笑 - '做非託管的事情' - 這聽起來很猥褻;-) – 2009-02-18 15:58:52

回答

3

我不認爲這是可能的使用C#。結構不會從System.ValueType繼承(但是鬆散地),直到編譯後,所以你不能通過多態性匹配Foo的方法簽名。泛型也出根據語言規範:

「非託管型是任何類型不引用類型,一個類型參數或通用結構類型和 不含類型不是非託管類型的字段「。

所以這就是爲什麼你不能採取T []的地址,無論結構約束。

你可以聲明一個結構類型(比如,酒吧)作爲參數傳遞給富,編譯代碼,並在IL級別更改方法簽名:

.method private hidebysig static void Foo(valuetype [mscorlib]System.ValueType[] args) cil managed

然後調用以及:

IL_0020: call void ConsoleApplication1.Program::Foo(valuetype [mscorlib]System.ValueType[])

雖然我能夠運行生成的程序,我不知道這有什麼樣的副作用。另外,即使你可以引用被修改的函數,你也不能從C#調用它,因爲在編譯之後,結構體不會從System.ValueType繼承,所以方法簽名將不匹配。

-1

這會工作:

public static void foo(System.Array data) 
    { 

    } 

    static void Main(string[] args) 
    { 
     foo(new int[10]); 
    } 

它並不強制數組是值類型的數組,但它的工作。

0
public void foo<T>(params T[] args) where T : struct { 
} 
public void SomeMethod() { 
    foo(1, 2, 3, 4); 
} 

您不應該輸入泛型參數,因爲編譯器會從foo的第一個參數中選取類型。