【问题标题】:How to get Initial Value of Field by Mono Cecil?Mono Cecil 如何获取字段的初始值?
【发布时间】:2019-06-12 03:02:59
【问题描述】:

我正在尝试使用 Mono Cecil 获取初始值作为 DLL 中公共字段的字符串。
这是我在类库中的代码:

namespace ClassLibrary1
{
    public static class Class1
    {
        public static string testField = "abc";
    }
}

我怎样才能得到“abc”?

【问题讨论】:

标签: c# .net mono.cecil


【解决方案1】:

我不确定 Cecil 是否提供 API 来检索此信息,但因为实例字段在类型的 构造函数静态字段静态构造函数 您可以在所需字段中查找商店。例如,给定这个类:

  .method private hidebysig specialname rtspecialname static 
        void .cctor () cil managed 
    {
        // Method begins at RVA 0x205f
        // Code size 21 (0x15)
        .maxstack 8

        IL_0000: ldstr "Foo"
        IL_0005: stsfld string Program::'value'
        IL_000a: call string Program::MyFunction()
        IL_000f: stsfld string Program::value2
        IL_0014: ret
    } // end of method Program::.cctor

你可以这样做:

using System;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;

namespace CecilRetrieveInitializer
{
    class Program
    {
        static Program()
        {
            Console.WriteLine("In cctor..");
        }

        static void Main(string[] args)
        {
            using (var a = AssemblyDefinition.ReadAssembly(typeof(Program).Assembly.Location))
            {
                var t = a.MainModule.GetType("CecilRetrieveInitializer.Program");
                var f = t.Fields.SingleOrDefault(c => c.Name == "value");
                Console.WriteLine(InitialValue(t, f));
                Console.WriteLine(InitialValue(t, t.Fields.SingleOrDefault(c => c.Name == "value2")));
            }

            string InitialValue(TypeDefinition t, FieldDefinition f)
            {
                var cctor = t.Methods.SingleOrDefault(m => m.Name == ".cctor");
                if (cctor == null)
                    throw new Exception("no field initialization...");

                var store = cctor.Body.Instructions.SingleOrDefault(i => i.OpCode == OpCodes.Stsfld && i.Operand == f);
                if (store.Previous.Operand.GetType() != typeof(string))
                    return store.Previous.Operand.ToString();

                return (string) store.Previous.Operand;
            }
        }

        static string MyFunction() => "Bar";

        public static string value = "Foo";
        public static string value2 = MyFunction();
        public const string value3 = "Bar";
    }
}

请记住,该字段可能会使用 non const 值进行初始化,在这种情况下,您可能无法(轻松)检索该值(请参阅 value2 >)。

另外,请注意,如果您将字段声明为 const,则可以使用 Constant 属性:

f = t.Fields.SingleOrDefault(c => c.Name == "value3");
Console.WriteLine(f.Constant);

【讨论】:

    猜你喜欢
    • 2021-07-05
    • 1970-01-01
    • 2011-03-12
    • 2020-02-13
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    相关资源
    最近更新 更多