c#反射:如何发出一个类



我有一个类,ReferenceObject,我想要发射到我创建的dll中。我如何做到这一点,而不使用Emit编写每个方法?我基本上想把这个类添加到我生成的dll中。

下面是类:

public class ReferenceObject
{
    private readonly int value;
    public ReferenceObject(int pValue)
    {
        value = pValue;
    }
    public override string ToString()
    {
        return value.ToString();
    }
    public int Value()
    {
        return value;
    }
    public int ID()
    {
        return value;
    }
    #region == Operator
    public static bool operator ==(int objLeft, ReferenceObject objRight)
    {
        return objLeft == objRight.value;
    }
    public static bool operator ==(ReferenceObject objLeft, int objRight)
    {
        return objLeft.value == objRight;
    }
    public static bool operator ==(string objLeft, ReferenceObject objRight)
    {
        return objLeft == objRight.value.ToString();
    }
    public static bool operator ==(ReferenceObject objLeft, string objRight)
    {
        return objLeft.value.ToString() == objRight;
    }
    #endregion
    #region != Operator
    public static bool operator !=(int objLeft, ReferenceObject objRight)
    {
        return objLeft != objRight.value;
    }
    public static bool operator !=(ReferenceObject objLeft, int objRight)
    {
        return objLeft.value != objRight;
    }
    public static bool operator !=(string objLeft, ReferenceObject objRight)
    {
        return objLeft != objRight.value.ToString();
    }
    public static bool operator !=(ReferenceObject objLeft, string objRight)
    {
        return objLeft.value.ToString() != objRight;
    }
    #endregion
    public override bool Equals(object obj)
    {
        if ((obj is ReferenceObject))
            return value == ((ReferenceObject)obj).value;
        if ((obj is int))
            return value == (int)obj;
        if ((obj is string))
            return value.ToString() == (string)obj;
        return false;
    }
    public override int GetHashCode()
    {
        return value;
    }
}
下面是我用来生成。dll 的代码
AppDomain domain = AppDomain.CurrentDomain;
AssemblyName aName = new AssemblyName("DynamicEnums");
AssemblyBuilder ab = domain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Save);
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
ConstructorInfo referenceObjectConstructor = typeof(ReferenceObject).GetConstructor(new[] { typeof(int) });
List<Type> types = new List<Type>();
foreach(ReferenceType rt in GetTypes())
{
    TypeBuilder tb = mb.DefineType(rt.Name, TypeAttributes.Public | TypeAttributes.BeforeFieldInit);
    ConstructorBuilder staticConstructorBuilder = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);
    ILGenerator staticConstructorILGenerator = staticConstructorBuilder.GetILGenerator();
    foreach (Reference r in GetReferences(rt.ID))
    {
        name = NameFix(r.Name);
        // Create a public, static, readonly field to store the
        // named ReferenceObject.
        FieldBuilder referenceObjectField = tb.DefineField(name, typeof(ReferenceObject), FieldAttributes.Static | FieldAttributes.Public | FieldAttributes.InitOnly);
        // Add code to the static constructor to populate the
        // ReferenceObject field:
        // Load the ReferenceObject's ID value onto the stack as a
        // literal 4-byte integer (Int32).
        staticConstructorILGenerator.Emit(OpCodes.Ldc_I4, r.ID);
        // Create a reference to a new ReferenceObject on the stack
        // by calling the ReferenceObject(int32 pValue) reference
        // we created earlier.
        staticConstructorILGenerator.Emit(OpCodes.Newobj, referenceObjectConstructor);
        // Store the ReferenceObject reference to the static
        // ReferenceObject field.
        staticConstructorILGenerator.Emit(OpCodes.Stsfld, referenceObjectField);
    }
    staticConstructorILGenerator.Emit(OpCodes.Ret);
    types.Add(tb.CreateType());
}
ab.Save(aName.Name + ".dll");

看一下反射。Emit插件:

你可以在这里下载Reflector:
http://www.reflector.net/

这是一个插件的链接:
http://reflectoraddins.codeplex.com/wikipage?title=ReflectionEmitLanguage& referringTitle =

编辑

您可能还想看看这篇文章:
http://www.codeproject.com/KB/dotnet/Creating_Dynamic_Types.aspx

回复评论

为什么不直接使用CodeDom,或者直接使用或编写一个"离线"代码生成器呢?反射。只有当你想在运行时创建类型时才需要Emit,否则它几乎是多余的。

请看我几年前做的一个例子

相关内容

  • 没有找到相关文章

最新更新