我有一个类,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,否则它几乎是多余的。
请看我几年前做的一个例子