수색…
어셈블리 란 무엇입니까?
어셈블리는 CLR (Common Language Runtime) 응용 프로그램의 구성 요소입니다. 정의한 모든 유형은 메소드, 특성 및 바이트 코드와 함께 어셈블리 내에 컴파일 및 패키지됩니다.
using System.Reflection;
Assembly assembly = this.GetType().Assembly;
어셈블리는 형식, 메소드 및 IL 코드뿐만 아니라 컴파일 및 런타임시에 검사하고 소비하는 데 필요한 메타 데이터도 포함합니다.
Assembly assembly = Assembly.GetExecutingAssembly();
foreach (var type in assembly.GetTypes())
{
Console.WriteLine(type.FullName);
}
어셈블리에는 완전하고 고유 한 ID를 설명하는 이름이 있습니다.
Console.WriteLine(typeof(int).Assembly.FullName);
// Will print: "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
이 이름에 PublicKeyToken
이 포함되어 있으면이를 강력한 이름 이라고합니다. 어셈블리의 강력한 이름 지정은 어셈블리와 함께 배포 된 공개 키에 해당하는 개인 키를 사용하여 서명을 만드는 프로세스입니다. 이 서명은 어셈블리를 구성하는 모든 파일의 이름과 해시가 들어있는 어셈블리 매니페스트에 추가되며 해당 PublicKeyToken
은 이름의 일부가됩니다. 동일한 강력한 이름을 가진 어셈블리는 동일해야합니다. 강력한 이름은 버전을 지정하고 어셈블리 충돌을 방지하는 데 사용됩니다.
Reflection을 사용하여 T의 객체를 만드는 법
기본 생성자 사용
T variable = Activator.CreateInstance(typeof(T));
매개 변수화 된 생성자 사용
T variable = Activator.CreateInstance(typeof(T), arg1, arg2);
리플렉션을 사용하여 객체 생성 및 속성 설정
우리가 propertyļ를 가진 Classy
클래스를 가지고 있다고하자.
public class Classy
{
public string Propertua {get; set;}
}
Propertua
사용하여 Propertua
를 설정 Propertua
방법 :
var typeOfClassy = typeof (Classy);
var classy = new Classy();
var prop = typeOfClassy.GetProperty("Propertua");
prop.SetValue(classy, "Value");
리플렉션 (그리고 캐싱)을 사용하여 enum의 속성 가져 오기
속성은 열거 형에서 메타 데이터를 나타내는 데 유용 할 수 있습니다. 이 값을 얻는 것은 느려질 수 있으므로 결과를 캐시하는 것이 중요합니다.
private static Dictionary<object, object> attributeCache = new Dictionary<object, object>();
public static T GetAttribute<T, V>(this V value)
where T : Attribute
where V : struct
{
object temp;
// Try to get the value from the static cache.
if (attributeCache.TryGetValue(value, out temp))
{
return (T) temp;
}
else
{
// Get the type of the struct passed in.
Type type = value.GetType();
FieldInfo fieldInfo = type.GetField(value.ToString());
// Get the custom attributes of the type desired found on the struct.
T[] attribs = (T[])fieldInfo.GetCustomAttributes(typeof(T), false);
// Return the first if there was a match.
var result = attribs.Length > 0 ? attribs[0] : null;
// Cache the result so future checks won't need reflection.
attributeCache.Add(value, result);
return result;
}
}
리플렉션을 통해 두 오브젝트 비교
public class Equatable
{
public string field1;
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
var type = obj.GetType();
if (GetType() != type)
return false;
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (var field in fields)
if (field.GetValue(this) != field.GetValue(obj))
return false;
return true;
}
public override int GetHashCode()
{
var accumulator = 0;
var fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (var field in fields)
accumulator = unchecked ((accumulator * 937) ^ field.GetValue(this).GetHashCode());
return accumulator;
}
}
참고 : 이 예제는 단순화를 위해 필드 기반 comparasion (정적 필드 및 속성 무시)을 수행합니다.