.net 框架 4.7.2...
编译后的表达式可以访问私有字段。当我使用完全相同的表达式并将其写入动态程序集时,使用CompileToMethod
,我会System.FieldAccessException
尝试读取私有字段。
我能做些什么来让动态程序集拥有与编译表达式相同的访问权限吗?有古老的传说说你不能。但我找不到任何类似于该声明的主要来源的东西。我不敢相信没有某种形式的程序集属性或允许访问的权限。
如果我保存程序集,我可以这样做吗?(将缓存的编组程序集写入磁盘是未来可能的功能)。
该应用程序将结构编组为特定领域的计算机音乐语言中的流。序列化不是一种选择(动态程序集中的动态代码违反访问的另一个示例)。
示例代码:
lambda 表达式成功读取了 ComplexStruct 的私有字段的值(如下所示)。如果使用 CompileToMethod 将相同的表达式发送到动态程序集,则会失败并出现访问异常。
ComplexStruct s = new ComplexStruct();
s.String1 = "abc";
// Pick a private field (one of the backing fields for a property)
FieldInfo fieldInfo = typeof(ComplexStruct).GetFields(BindingFlags.NonPublic | BindingFlags.Instance)[0];
var structArgument = Expression.Parameter(typeof(ComplexStruct));
var lambda = Expression.Lambda<Func<ComplexStruct,String>>(
Expression.Field(structArgument, fieldInfo), // return the value of the private field.
structArgument);
Func<ComplexStruct,String> fn = lambda.Compile();
String result = fn(s);
Assert.AreEqual(structArgument.String1, result);
具有私有字段的结构:
// (Complex compared to simple struct where all fields
// are public or the struct is unmanaged in case you were wondering)
public struct ComplexStruct : IEquatable<ComplexStruct>
{
public String String1 { get; set; } // the backing field for this property gets read.
public String String2 { get; set; }
public String String3 { get; }
public ComplexStruct(String v1, String v2)
{
String1 = v1;
String2 = v2;
}
public bool Equals(ComplexStruct other)
{
return String1 == other.String1 && String2 == other.String2;
}
}
组件的创建:
AppDomain myAppDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "DynamicAssembly";
this.saveAssembly = ServiceBase.DEBUG;
assemblyBuilder = myAppDomain.DefineDynamicAssembly(
myAsmName,
saveAssembly? AssemblyBuilderAccess.RunAndSave: AssemblyBuilderAccess.RunAndCollect);