簡體   English   中英

是否有可能欺騙C#編譯器來封裝Nullable <T> 結構螞蟻不是它的價值?

[英]Is it possible to cheat C# compiler to box Nullable<T> struct ant not its value?

嗯,問題可能看起來很奇怪。 它確實是。
然而,我堅信這些黑客有助於理解語言和.net平台。

C#編譯器如何處理可空類型意味着這個問題。

Nullable<T>是一個結構。 但編譯器框不是這個結構,而是它保存的值或只是空引用。

在盒裝Nullable的情況下,拆箱將如何工作也很有用。

Nullable<int> myInt = boxedStruct as Nullable<int>;

在這里我認為boxedStruct不是一個盒裝的int而是整個結構。

好吧,可能是在CLR級別對Nullables的處理方式不同,因為我無法理解下面程序的ouptut。

class Program
{
    public static bool? Property { get; set; }

    static void Main(string[] args)
    {
        Property = true;

        var valueType = typeof (Program).GetProperty("Property").GetValue(null).GetType();
        var propType = typeof (Program).GetProperty("Property").PropertyType;

        Console.WriteLine("Value's type '{0}' is the same as type of the property '{1}' - '{2}'", valueType, propType, valueType == propType);
        Console.ReadKey();
    }
}

輸出:

值的類型'System.Boolean'與屬性'System.Nullable`1 [System.Boolean]'的類型相同 - ''False'

更新:

這里的規范(ECMA 335)說:

I.8.2.4值的裝箱和拆箱
...
如果值類型是可空類型 - 定義為值類型System.Nullable的實例化 - 結果是其類型為T的Value屬性的空引用或按位副本,具體取決於其HasValue屬性(分別為false和true) 。

所以如果我理解正確的話。 Nulllable Nullable<T> strcut不能裝入.Net Framework中,它不僅不可能用C#編譯器,而且用CLR也是如此。

我猜想你要問的問題是:

你可以Nullable<int>值而不產生空引用或盒裝int值,而是實際裝箱的Nullable<int>嗎?

沒有。

有可能欺騙C#編譯器來裝箱Nullable<T>嗎?

不,因為不是編輯誰做拳擊,它是CLR。 是的,可空類型的裝箱是在CLR本身中專門處理的。

那么有沒有辦法在沒有這種特殊處理的情況下裝入可以為空的結構? 也沒有。

但是可以打包另一個看起來像Nullable<T> (確保它具有適當的布局),並且在未記錄的關鍵字和內存黑客的幫助下,讓CLR認為盒裝對象實際上是Nullable<T>
謹防! 此代碼僅用於教育目的。 我不能保證它可以在其他平台上工作或在不同條件下工作,因為它依賴於托管對象的底層布局。

public static unsafe object BoxNullable<T>(T? nullable) where T : struct
{
    object scam = new NullableFake<T>(nullable);
    TypedReference tr = __makeref(scam);
    IntPtr typehandle = typeof(Nullable<T>).TypeHandle.Value;
    IntPtr* trstruct = (IntPtr*)&tr;
    **((IntPtr**)trstruct[0]) = typehandle;
    return scam;
}

struct NullableFake<T> where T : struct
{
    public readonly T? Value;

    public NullableContainer(T? nullable)
    {
        Value = nullable;
    }
}

所述NullableFake<T>結構具有的布局相同Nullable<T>所以它是安全的使用它的拳擊。 TypedReference用於獲取指向變量的指針(包含指向對象的指針),從而暴露對象本身。 對象內存布局中的第一個值是指向對象類型的指針。 覆蓋它會導致CLR認為類型不同。

我不知道有任何更安全的方法。

暫無
暫無

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

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