Hello guys,
ILGenerator.Emit(OpCode, FieldInfo) method throws ArgumentNullException if
the input parameter is an instance of
System.Runtime.Serialization.SerializationFieldInfo class. I believe this is
a bug in the framework (I am running on .NET2.0). Could you please help me if
I do something wrong, or finding a workaround for the problem?
Below is the short sample code. It presents two classes (SubClass,
SuperClass), which have the private fields using the same name. I iterate
through the fields of the SuperClass and building a DynamicMethod for fast
invokation. In the example, there are two iterations (since there are two
fields). The fieldinfo of SuperClass.id is a RuntimeFieldInfo instance and
works fine. The fieldinfo of SubClass.id is an instance of
SerializationFieldInfo and crashes. Here is the code:
using System;
using System.Text;
using System.Runtime.Serialization;
using System.Reflection.Emit;
using System.Reflection;
namespace Test
{
[Serializable]
public class SubClass
{
private string id = "subClassID";
}
[Serializable]
public class SuperClass : SubClass
{
private string id = "superClassID";
}
public class DynamicMethodIssue
{
public delegate object GetDelegate(object template);
public static void Main(string[] args)
{
MemberInfo[] serializableMembers =
FormatterServices.GetSerializableMembers(typeof(SuperClass));
foreach (FieldInfo fieldInfo in serializableMembers)
{
GetDelegate d = CreateGetField(fieldInfo);
// TODO: Store the delegate for later invocation...
Console.WriteLine();
}
}
private static GetDelegate CreateGetField(FieldInfo field)
{
Type[] args = new Type[] { typeof(object) };
// Method name does not matter (no name clashing) since we
do not add the methods to a dynamic class.
DynamicMethod getMethod = new DynamicMethod("GetValue",
typeof(object), args, field.DeclaringType);
ILGenerator gen = getMethod.GetILGenerator();
// If DeclaringType is of value type, we would need
special treatment, but we do not bother.
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Castclass, field.DeclaringType);
gen.Emit(OpCodes.Ldfld, field);
//If the parameter is a primitive type, it has to be
unboxed.
if (field.FieldType.IsValueType) gen.Emit(OpCodes.Box,
field.FieldType);
gen.Emit(OpCodes.Ret);
GetDelegate result =
(GetDelegate)getMethod.CreateDelegate(typeof(GetDelegate));
return result;
}
}
}
Peter Ritchie [C# MVP] - 11 Mar 2008 19:12 GMT
It's a bug in that it shouldn't be an ArgumentNullException; but it's not a
bug that an exception is being raised: Emit only supports RuntimeFieldInfo
fields, not SerializationFieldInfo.

Signature
Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#
> Hello guys,
>
[quoted text clipped - 75 lines]
>
>