簡體   English   中英

C#類型參數規范

[英]C# type parameters specification

mscorlib庫中的某些特殊CLI類型( ArgIteratorTypedReferenceRuntimeArgumentHandle類型)不能用作構造通用類型/方法的通用類型參數:

void Foo<T>() { }
void Bar() { Foo<ArgIterator>(); }

提供編譯器錯誤:

error CS0306: The type 'System.ArgIterator' may not be used as a type argument

但這在C#規范中根本沒有記錄。

此類型是CLI規范的一部分,還是CLR實現提供的此類型,並且上述行為不應在C#規范中記錄?

首先,喬恩再次是正確的-這些家伙是非常特殊的類型,其值不能轉換為對象,因此不能用作類型參數。 所有類型參數必須是其值可轉換為對象的類型。

要回答有關文檔的問題:

沒有記錄用於處理可變參數方法的特殊功能。 它們不是C#語言本身的一部分-不需要與該語言兼容的實現即可與支持可變參數方法的語言進行互操作。 這些功能也沒有作為編譯器文檔的一部分記錄在MSDN中。 這些不是“官方支持”的功能。

不幸的是,但是預算太多了,我想大多數人都會同意,我們會寫出更好的功能並修復錯誤,而不是花錢去記錄功能,這些功能實際上是99.99%的用戶永遠不會使用,甚至如果他們得到了支持,但不是。

如果您想使用可變參數方法在C#中進行互操作,那您就該靠自己了。 祝好運!

我相信是因為這些類型是“特殊的”,因為它們無法轉換為object 只能將可以轉換為object類型指定為類型參數。 順便說一句,指針也是如此。

我找不到該文件的記錄位置(在4.4.1中已為指針記錄該文件),但前一天Eric Lippert在評論中提到了它。

這僅僅是一個利益的事情,或者是你想使用這種事情真正一些事情?

就像一條評論一樣,當您嘗試使用這種不能轉換為對象的類型編譯代碼時,可以從中獲得更多樂趣。 鍵入時,Visual Studio會提出這里的所有方法作為建議. (點)。

  ArgIterator.ReferenceEquals(new object(), new object());  // OK; static method inherited from System.Object

  var strange = default(ArgIterator);
  strange.End();          // OK; non-virtual method defined in the struct
  strange.GetHashCode();  // OK; method overridden in the struct
  strange.ToString();     // compile-time error; method overriden in System.ValueType, inherited but not overridden in the struct
  strange.GetType();      // compile-time error; non-virtual method inherited from System.Object

您提供的所有三個示例都是結構,而不是類,因此我懷疑這是解決問題的關鍵。 文檔中有關編譯器錯誤消息的示例還表明,如果您使用指向泛型類型的指針,則該類型將失敗。

CLI規范的第8.2.4節調用值類型,該值類型可以包含指向評估堆棧的“ byref-like”類型的指針,並指出不能將它們裝箱。 它顯式調用System.RuntimeArgumentHandleSystem.TypedReference作為此類類型的示例,但未提供詳盡列表。 9.4節繼續指出,不能使用byref類型,類似於byref的類型和System.Void來實例化泛型類型或方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM