gpt4 book ai didi

c# - ILGenerator 属性不是实例

转载 作者:行者123 更新时间:2023-11-30 17:01:37 26 4
gpt4 key购买 nike

我想得到这个:

.property instance class [WorldTool.Core]WorldTool.IInputPort SomePort
{
.get instance class [WorldTool.Core]WorldTool.IInputPort WorldTool.Core.Tests.SomeOperatorInstance::get_SomePort()
}

但是我得到了这个:

.property class class [WorldTool.Core]WorldTool.IInputPort SomePort
{
.get instance class [WorldTool.Core]WorldTool.IInputPort SomeOperatorInstanceProxy::get_SomePort()
}

为什么我得到的是“.property 类类”而不是“.property 实例类”?这是我用来生成它的内容:

private void CreateProperty(TypeBuilder typeBuilder, PropertyInfo propertyInfo)
{
var propertyBuilder = typeBuilder.DefineProperty(propertyInfo.Name,
PropertyAttributes.HasDefault,
propertyInfo.PropertyType,
Type.EmptyTypes);

var methodBuilder = typeBuilder.DefineMethod(GET_PREFIX + propertyInfo.Name,
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
propertyInfo.PropertyType,
Type.EmptyTypes);

var methodGenerator = methodBuilder.GetILGenerator();
methodGenerator.DeclareLocal(propertyInfo.PropertyType);
methodGenerator.Emit(OpCodes.Nop);
methodGenerator.Emit(OpCodes.Ldarg_0);
methodGenerator.Emit(OpCodes.Ldstr, propertyInfo.Name);
methodGenerator.Emit(OpCodes.Call, typeof(IInputPort).IsAssignableFrom(propertyInfo.PropertyType) ? GetNamedInputPort : GetNamedOutputPort);
methodGenerator.Emit(OpCodes.Stloc_0);

var targetInstruction = methodGenerator.DefineLabel();
methodGenerator.Emit(OpCodes.Br_S, targetInstruction);

methodGenerator.MarkLabel(targetInstruction);
methodGenerator.Emit(OpCodes.Ldloc_0);

methodGenerator.Emit(OpCodes.Ret);

propertyBuilder.SetGetMethod(methodBuilder);
}

最佳答案

您需要在定义属性时指定调用约定。

你有:

var propertyBuilder = typeBuilder.DefineProperty(
propertyInfo.Name,
PropertyAttributes.HasDefault,
propertyInfo.PropertyType,
Type.EmptyTypes);

你需要:

var propertyBuilder = typeBuilder.DefineProperty(
propertyInfo.Name,
PropertyAttributes.HasDefault,
CallingConventions.HasThis, // ding ding ding
propertyInfo.PropertyType,
Type.EmptyTypes);

对于任何想重复我的发现的人,这里是我使用的测试代码:

namespace EmitTest
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection.Emit;
using System.Reflection;

public class TestPropertyBuilde
{
TypeBuilder tb;
FieldBuilder countFB;

// The code in this class generates the code in the following comment:
/*
namespace EmitTest
{
public class TestType
{
private int count;
public int TestProperty
{
get
{
return this.count;
}
}
public TestType()
{
this.count = 1;
}
}
}
*/

public void Build()
{
AssemblyName name = new AssemblyName( "GeneratedAssm" );

AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(
name,
AssemblyBuilderAccess.RunAndSave,
@"C:\Users\antiduh\Desktop\EmitTest" );

ModuleBuilder mb = assembly.DefineDynamicModule( name.Name, name.Name + ".dll" );

this.tb = mb.DefineType( "EmitTest.TestType", TypeAttributes.Public );

CreateVariable();

CreateConstructor();

CreateProperty( "TestProperty", typeof( int ) );

Type dummy = tb.CreateType();
assembly.Save( "GeneratedAssm.dll" );
}

private void CreateVariable()
{
this.countFB = tb.DefineField( "count", typeof( int ), FieldAttributes.Private );
}

private void CreateConstructor()
{
ConstructorBuilder ctor0 = tb.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes );


var gen = ctor0.GetILGenerator();

gen.Emit( OpCodes.Ldarg_0 );
gen.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) );

gen.Emit( OpCodes.Ldarg_0 );
gen.Emit( OpCodes.Ldc_I4_1 );
gen.Emit( OpCodes.Stfld, countFB);

gen.Emit( OpCodes.Ret );
}

private void CreateProperty(string propertyName, Type propType )
{

var propertyBuilder = tb.DefineProperty(
propertyName,
PropertyAttributes.HasDefault,
CallingConventions.HasThis,
propType,
Type.EmptyTypes );

var methodBuilder = tb.DefineMethod(
"get_" + propertyName,
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
propType,
Type.EmptyTypes );

var methodGenerator = methodBuilder.GetILGenerator();

methodGenerator.Emit( OpCodes.Ldarg_0 );
methodGenerator.Emit( OpCodes.Ldfld, countFB );
methodGenerator.Emit( OpCodes.Ret );

propertyBuilder.SetGetMethod( methodBuilder );
}
}

关于c# - ILGenerator 属性不是实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20851664/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com