簡體   English   中英

如何從.NET程序集中讀取數組初始化值

[英]How to read array initializer values from .NET assembly

如何讀取值,讓我們說:'99'來自包含此代碼的程序集

using Sytem; 

public class Class1
{
    public Class1() {
        // array initializer, want to read '99', '100'... from assembly
        var a = new double[,] { { 1, 2, 3 }, { 99, 100, 101 } };
        // ...
    }

}

到目前為止我做了什么

ILDASM中的方法:

.method /*06000001*/ public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
// SIG: 20 00 01
{
  // Method begins at RVA 0x2080
  // Code size       29 (0x1d)
  .maxstack  3
  .locals /*11000001*/ init ([0] float64[0...,0...] a)
  .language '{3F5162F8-07C6-11D3-9053-00C04FA302A1}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
// Source File 'c:\Users\heini19\Documents\Visual Studio 2013\Projects\WcfService1\ClassLibrary1\Class1.cs' 
//000005:         public Class1() {
  IL_0000:  /* 02   |                  */ ldarg.0
  IL_0001:  /* 28   | (0A)000011       */ call       instance void [mscorlib/*23000001*/]System.Object/*01000001*/::.ctor() /* 0A000011 */
  IL_0006:  /* 00   |                  */ nop
  IL_0007:  /* 00   |                  */ nop
//000006:             // array initializer, want to read '99', '100' etc.
//000007:             var a = new double[,] { { 1, 2, 3 }, { 99, 100, 101 } };
  IL_0008:  /* 18   |                  */ ldc.i4.2
  IL_0009:  /* 19   |                  */ ldc.i4.3
  IL_000a:  /* 73   | (0A)000012       */ newobj     instance void float64[0...,0...]/*1B000001*/::.ctor(int32,
                                                                                                         int32) /* 0A000012 */
  IL_000f:  /* 25   |                  */ dup
  IL_0010:  /* D0   | (04)000001       */ ldtoken    field valuetype '<PrivateImplementationDetails>{975506E6-7C24-4C2B-8956-C1B9CF8B80C4}'/*02000003*//'__StaticArrayInitTypeSize=48'/*02000004*/ '<PrivateImplementationDetails>{975506E6-7C24-4C2B-8956-C1B9CF8B80C4}'/*02000003*/::'$$method0x6000001-1' /* 04000001 */
  IL_0015:  /* 28   | (0A)000014       */ call       void [mscorlib/*23000001*/]System.Runtime.CompilerServices.RuntimeHelpers/*01000015*/::InitializeArray(class [mscorlib/*23000001*/]System.Array/*01000016*/,
                                                                                                                                                            valuetype [mscorlib/*23000001*/]System.RuntimeFieldHandle/*01000017*/) /* 0A000014 */
  IL_001a:  /* 0A   |                  */ stloc.0
//000008:             // ...
//000009:         }
  IL_001b:  /* 00   |                  */ nop
  IL_001c:  /* 2A   |                  */ ret
} // end of method Class1::.ctor

編譯器使用字段$$method0x6000001-1為初始化值創建了struct <PrivateImplementationDetails>{975506E6-7C24-4C2B-8956-C1B9CF8B80C4} ,並使用RuntimeHelpers.InitializeArray在運行時初始化新數組。 C#中定義的原始值似乎存儲在字段中並使用字段句柄進行復制? 但這些價值觀是如何規划的?

必須有一些更好/更簡單的方法來從程序集中讀取這些常量?

沒有回應

你想要做的就是不可能做到的事情(注意你的例子中的單個案例可能是可行的,但可能無法滿足你的全部需求)

<PrivateImplementationDetails>僅在某些情況下由C#編譯器創建(似乎超過一定大小的數字數組)。 對於所有其他情況,完成構造函數中的直接初始化。 有關示例,請參閱http://goo.gl/iC6MRv

請注意,您看到的IL代碼並非“寫在石頭上”......沒有規則要求C#編譯器如何創建數組初始值設定項。 例如,Roslyn(我給出的鏈接是由Roslyn生成的)使用PrivateImplementationDetails而不是<PrivateImplementationDetails>{975506E6-7C24-4C2B-8956-C1B9CF8B80C4} 誰知道Mono編譯器生成了什么代碼。

在最一般的情況下,如果不執行構造函數(因此實例化類)並查看獲取的對象,則無法知道初始化數組的值。 但這顯然還有其他問題(類的初始化可能有副作用,或者可能需要參數)

暫無
暫無

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

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