【发布时间】:2018-01-06 13:45:30
【问题描述】:
我正在使用这样的代码在运行时定义 protobuf-net 架构。而且我遇到了错误:
CustomAttributeBuilder contractMem = new CustomAttributeBuilder(
contractMemInfoCon, new object[] { index });
因为“值不能为空”。请帮我解决这个问题。
AssemblyName oAssemblyName = new AssemblyName();
oAssemblyName.Name = "TEST";
AssemblyBuilder oAssmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly("Test", AssemblyBuilderAccess.Run);
ModuleBuilder oModule = oAssmBuilder.DefineDynamicModule("TestModule.Module");
TypeBuilder oTypeBuilder = oModule.DefineType("TestType", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Serializable);
ConstructorBuilder constructor = oTypeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
//For Defining protocontract
ConstructorInfo contractInfoCon = typeof(ProtoBuf.ProtoContractAttribute).GetConstructor(new Type[0]);
CustomAttributeBuilder cab = new CustomAttributeBuilder(contractInfoCon, new object[0]);
oTypeBuilder.SetCustomAttribute(cab);
string sDataType = "", sPropertyName = "";
int index = 0;
//oFields contains SP columns
foreach (Types.Field oField in oFields)
{
sPropertyName = oField.ID;
sDataType = oField.DataType;
index = index + 1;
FieldBuilder field = oTypeBuilder.DefineField(sPropertyName, oField.DataType, FieldAttributes.Public);
PropertyBuilder property =
oTypeBuilder.DefineProperty("_" + sPropertyName,
System.Reflection.PropertyAttributes.None,
oField.DataType,
new Type[] { oField.DataType });
MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
MethodBuilder currGetPropMthdBldr =
oTypeBuilder.DefineMethod("get_value",
GetSetAttr,
oField.DataType,
Type.EmptyTypes);
ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, field);
currGetIL.Emit(OpCodes.Ret);
MethodBuilder currSetPropMthdBldr =
oTypeBuilder.DefineMethod("set_value",
GetSetAttr,
null,
new Type[] { oField.DataType });
ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, field);
currSetIL.Emit(OpCodes.Ret);
property.SetGetMethod(currGetPropMthdBldr);
property.SetSetMethod(currSetPropMthdBldr);
ConstructorInfo contractMemInfoCon = typeof(ProtoBuf.ProtoMemberAttribute).GetConstructor(new [] { oField.DataType });
CustomAttributeBuilder contractMem = new CustomAttributeBuilder(contractMemInfoCon, new object[] { index });
property.SetCustomAttribute(contractMem);
}
【问题讨论】:
-
请尝试edit您的问题,为您的问题添加一些细节。因为它是我们不能告诉你到目前为止到底尝试了什么,什么不起作用。事实上,minimal reproducible example 构建样本
DataSet将是理想的。就目前而言,这个问题不太可能得到回答。请参阅How to Ask 和codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question,了解如何提出更有可能得到回答的问题。说了这么多,你可以从Serializing a dataTable using protobuf开始。 -
另外,尝试更全面地标记未来的问题。你在用protobuf-net吗?还是Google.Protobuf?还是别的什么?
-
嗨; protobuf-net 作者在这里;我可以问:你为什么在这里使用 TypeBuilder?您试图通过元编程实现什么目标? protobuf-net 中的大多数东西都可以通过
RuntimeTypeModelAPI 在运行时配置 - 我强烈怀疑这里的 IL 东西会分散您实际尝试做的事情的注意力。那么:您真正想做的事情是什么? -
数据集是邪恶的......只用于简单的东西,绝对不能用于任何分布式......
-
你找到解决了吗?我同样需要将数据集来回发送到 gRPC 服务。
标签: c# serialization protobuf-net typebuilder