2
我正在使用ILGenerator創建一個函數,並在發出指定實例時設置屬性的值。這是我正在處理的解決方案的性能方面的主要原因。我有一個基本的代碼形式,它應該採用2個對象並通過IL加載它們以調用設置函數。我發現的問題是我通過設置的值似乎被忽略,另一個似乎產生的值被設置在它的位置。無法通過對象上的IL Emit設置某些類型值
這是LinqPad提出的基本用法的例子,我已經創建演示此問題:
void Main()
{
var instance = new TestClass
{
Id = new Guid("f0564ce7-f249-4105-8fc4-2c65cfe095f6"),
StringValue = "Something",
IntValue = 0
};
MethodOne(instance);
}
private void MethodOne(TestClass instance)
{
var setStringMethod = GenerateMethodAssignment("StringValue");
setStringMethod(instance, "Something Else");
var setGuidMethod = GenerateMethodAssignment("Id");
setGuidMethod(instance, new Guid("f8b0fae2-40bb-422a-815f-2300cceb4329"));
var setIntMethod = GenerateMethodAssignment("IntValue");
setIntMethod(instance, 100);
instance.Dump();
}
// Define other methods and classes here
public class TestClass
{
public Guid Id { get; set; }
public string StringValue { get; set; }
public int IntValue { get; set; }
}
private Action<object, object> GenerateMethodAssignment(string propName)
{
var setMethod = typeof(TestClass).GetProperty(propName).GetSetMethod();
var argTypes = new Type[] { typeof(object), typeof(object) };
var method = new DynamicMethod(Guid.NewGuid().ToString(), null, argTypes, GetType(), true);
var ilGenerator = method.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Call, setMethod);
ilGenerator.Emit(OpCodes.Ret);
var action = (Action<object, object>)method.CreateDelegate(typeof(Action<object, object>));
return action;
}
的字符串值被設置好的,但一個GUID或整型值不按我的預期設置。對於IL來說,我是相當新的,並且可能對代碼的期望過高,因爲代碼很簡單。
但即使如此,我注意到多次運行此代碼似乎以看似順序的順序生成IntValue
和Id
的值,所以我很好奇這些值是從哪裏來的。
當然!沒有跨過我的想法,認爲這是理所當然的。謝謝! –
由於某些原因,我不得不使用'OpCodes.Unbox_Any'而不是'OpCodes.Unbox'。我無法從文檔中完全弄清楚它,但它看起來像'Unbox_Any'執行一個額外的操作,'Unbox'沒有。 – Timo