Emit의 동적 유형 TypeBuilder에서 클래스 태그 생성에 대한 생각
9947 단어 builder
TypeBuilder를 이용하면 하나의 유형을 동적으로 만들 수 있습니다. 현재 하나의 수요가 있습니다. 동적으로 dll을 생성하고 유형EmployeeEx를 만듭니다. 원래 dll에 있는 Employee 클래스를 계승하고 Employee 클래스의 모든 클래스 표시를 포함해야 합니다.
인터넷에는 많은 예가 있는데,
// TypeBuilder。
TypeBuilder myTypeBuilder = myModBuilder.DefineType(typeName,
TypeAttributes.Public);
myTypeBuilder.SetParent(type);
대략적인 처리 방법은 다음과 같다.
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeof(SerializableAttribute).GetConstructor(Type.EmptyTypes), new Type[] { });
myTypeBuilder.SetCustomAttribute(customAttributeBuilder);
att = type.GetCustomAttributes(typeof(DefaultPropertyAttribute), false);
if (att != null && att.Length > 0) {
DefaultPropertyAttribute dea = att[0] as DefaultPropertyAttribute;
customAttributeBuilder = new CustomAttributeBuilder(typeof(DefaultPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { dea.Name });
myTypeBuilder.SetCustomAttribute(customAttributeBuilder);
}
그러나 이것은 이미 알고 있는 클래스 표시가 Serializable 또는Default Property입니다. 만약에 원래 dll에 있는 Employee에 사용자 정의 표시를 추가하면, 클래스 표시, Type Builder를 어떻게 동적으로 계승할 수 있는지 프로그램을 바꿔야 합니다.SetCustom Attribute는 SetCustom Attribute(Custom Attribute Builder custom Builder)와 SetCustom Attribute(Constructor Info con,byte[] binary Attribute) 2개를 리셋합니다.둘 다 클래스 태그를 구성하려면 ConstructorInfo가 필요합니다.우리가 유형 Employee를 통해 얻은 클래스 표시는 반사된 Object[] atts = type입니다.GetCustomAttributes(false);이것은 Object 배열이므로 ConstructorInfo에 직접 사용할 수 없습니다.
그래서 아래의 코드가 생겨서 동적으로 표시가 생겼다.
#region
object[] atts = type.GetCustomAttributes(false);
if (atts != null && atts.Length > 0) {
foreach (Attribute item in atts) {
if (item == null) continue;
try {
CustomAttributeBuilder c = null;
ConstructorInfo[] conInfos = item.GetType().GetConstructors();
ConstructorInfo cons = conInfos[conInfos.Length - 1];
ParameterInfo[] args = cons.GetParameters();
List<Type> argsList = new List<Type>();
List<object> argsValue = new List<object>();
if (args.Length > 0) {
foreach (var arg in args) {
argsList.Add(arg.ParameterType);
PropertyInfo pi = item.GetType().GetProperty(arg.Name.Substring(0, 1).ToUpper() + arg.Name.Substring(1));//
if (pi != null) {
argsValue.Add(pi.GetValue(item, null));
} else {
pi = item.GetType().GetProperty(arg.Name.Remove(0, 1));// p+Name
if (pi != null) {
argsValue.Add(pi.GetValue(item, null));
} else {
argsValue.Add(null);
}
}
}
}
PropertyInfo[] pis = item.GetType().GetProperties();
if (pis.Length > 0) {
List<PropertyInfo> piList = new List<PropertyInfo>();
List<object> valueList = new List<object>();
object[] pValues = new object[pis.Length];
for (int i = 0; i < pis.Length; i++) {
if (pis[i].CanWrite) {
pValues[i] = pis[i].GetValue(item, null);
if (pValues[i] != null) {
piList.Add(pis[i]);
valueList.Add(pValues[i]);
}
}
}
if (piList.Count > 0) {
c = new CustomAttributeBuilder(cons, argsValue.ToArray(), piList.ToArray(), valueList.ToArray());
} else {
c = new CustomAttributeBuilder(cons, argsValue.ToArray());
}
} else {
c = new CustomAttributeBuilder(cons, argsValue.ToArray());
}
myTypeBuilder.SetCustomAttribute(c);
} catch (Exception ex) {
throw new Exception(string.Format("{0} [{1}] :{2}", typeName, item.ToString(),ex.ToString()));
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin에서 가장 적합한 Builder 모드를 생각해 봤습니다.자바로 작성된 버라이더 모드의 구현은 코틀린으로 대체됐지만, 의외로 정보가 적다는 것을 느껴 이 기회를 틈타 가장 적합한 버라이더 모드를 생각해봤다. 이 기사는 Builder 모드에 대해 자세히 설명하지 않습니다. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.