English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
반영은 프로그램이 자신의 상태나 행동을 접근하고 검사하고 수정할 수 있는 능력을 의미합니다。
프로그램 집합은 모듈을 포함하며, 모듈은 타입을 포함하며, 타입은 멤버를 포함합니다. 반영은 프로그램 집합, 모듈, 타입을 포장하는 객체를 제공합니다。
반영을 사용하여 타입의 예제를 동적으로 생성할 수 있으며, 타입을 기존 객체에 바인딩하거나 기존 객체에서 타입을 가져올 수 있습니다. 그런 다음, 타입의 메서드를 호출하거나 그 필드와 속성에 접근할 수 있습니다。
점점:
1、반영은 프로그램의 유연성과 확장성을 높입니다。
2、결합도를 낮추고 자율적 능력을 높입니다。
3、프로그램은 어떤 클래스의 객체도 생성하고 제어할 수 있으며, 대상 클래스를 미리 코드로 설정할 필요가 없습니다。
단점:
1、성능 문제:반영은 주로 설명 작업으로, 필드와 메서드에 접근할 때 직접 코드보다 느릴 수 있습니다. 따라서 반영 메커니즘은 유연성과 확장성이 매우 높은 시스템 프레임워크에 주로 적용되며, 일반 프로그램에서는 사용하지 않는 것이 좋습니다。
2、反射는 프로그램 내부 로직을 흐리게 만들 수 있습니다;프로그래머는 소스 코드에서 프로그램의 로직을 볼 것을 원하지만, 반영은 소스 코드를 돌파하는 기술을 통해 로직을 흐리게 만들어, 유지보수 문제를 야기할 수 있습니다. 반영 코드는 해당 직접 코드보다 복잡합니다。
反射(Reflection)의 용도는 다음과 같습니다:
이는 실행 중에 특성(attribute) 정보를 확인할 수 있게 합니다.
모음에서 다양한 타입을 검토하고 이러한 타입을 인스턴스화할 수 있게 합니다.
메서드와 프로퍼티(property)의 지연 바인딩을 허용합니다.
이는 실행 중에 새로운 타입을 생성하고 이러한 타입을 사용하여 일정한 작업을 수행할 수 있게 합니다.
우리는 위의 장에서 이미 언급했듯이, 반영(Reflection)을 사용하여 특성(attribute) 정보를 확인할 수 있습니다.
System.Reflection 의 MemberInfo 객체는 초기화되어야 하며, 클래스와 관련된 특성(attribute)을 발견하기 위해 사용됩니다. 이를 위해 다음과 같이 타겟 클래스의 객체를 정의할 수 있습니다:
System.Reflection.MemberInfo info = typeof(MyClass);
아래 프로그램은 이를 보여줍니다:
using System; [AttributeUsage(AttributeTargets.All)] public class HelpAttribute : System.Attribute { public readonly string Url; public string Topic // Topic은 이름(named) 파라미터입니다 { get { return topic; } set { topic = value; } } public HelpAttribute(string url) // url은 위치(positional) 파라미터입니다 { this.Url = url; } private string topic; } [HelpAttribute("MyClass 클래스에 대한 정보")] class MyClass { } namespace AttributeAppl { class Program { static void Main(string[] args) { System.Reflection.MemberInfo info = typeof(MyClass); object[] attributes = info.GetCustomAttributes(true); for (int i = 0; i < attributes.Length; i++) { System.Console.WriteLine(attributes[i]); } Console.ReadKey(); } } }
위의 코드가 컴파일되고 실행될 때, 클래스에 추가된 MyClass 에 대한 커스텀 특성을 사용하겠습니다:
HelpAttribute
이 예제에서는, 이전 장에서 생성한 DeBugInfo 특성을 사용하여 반사(Reflection)를 통해 읽습니다 Rectangle 클래스의 메타데이터.
using System; using System.Reflection; namespace BugFixApplication { // BugFix라는 사용자 정의 특성이 클래스와 멤버에 할당되었습니다 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] public class DeBugInfo : System.Attribute { private int bugNo; private string developer; private string lastReview; public string message; public DeBugInfo(int bg, string dev, string d) { this.bugNo = bg; this.developer = dev; this.lastReview = d; } public int BugNo { get { return bugNo; } } public string Developer { get { return developer; } } public string LastReview { get { return lastReview; } } public string Message { get { return message; } set { message = value; } } } [DeBugInfo(45, "Zara Ali", "12/8/2012" Message = "Return type mismatch")] [DeBugInfo(49, "Nuha Ali", "10/10/2012" Message = "Unused variable")] class Rectangle { // 성원 변수 protected double length; protected double width; public Rectangle(double l, double w) { length = l; width = w; } [DeBugInfo(55, "Zara Ali", "19/10/2012" Message = "Return type mismatch")] public double GetArea()} { return length * width; } [DeBugInfo(56, "Zara Ali", "19/10/2012) public void Display() { Console.WriteLine("长度: {0}", length); Console.WriteLine("宽度: {0}", width); Console.WriteLine("面积: {0}", GetArea()); } }//end class Rectangle class ExecuteRectangle { static void Main(string[] args) { Rectangle r = new Rectangle(4.5, 7.5); r.Display(); Type type = typeof(Rectangle); // 遍历 Rectangle 类的特性 foreach (Object attributes in type.GetCustomAttributes(false)) { DeBugInfo dbi = (DeBugInfo)attributes; if (null != dbi) { Console.WriteLine("错误编号: {0}", dbi.BugNo); Console.WriteLine("开发者: {0}", dbi.Developer); Console.WriteLine("最后审查日期: {0}", dbi.LastReview); Console.WriteLine("备注: {0}", dbi.Message); } } // 遍历方法特性 foreach (MethodInfo m in type.GetMethods()) { foreach (Attribute a in m.GetCustomAttributes(true)) { DeBugInfo dbi = (DeBugInfo)a; if (null != dbi) { Console.WriteLine("错误编号: {0}, 用于方法: {1} dbi.BugNo, m.Name); Console.WriteLine("开发者: {0}", dbi.Developer); Console.WriteLine("最后审查日期: {0}", dbi.LastReview); Console.WriteLine("备注: {0}", dbi.Message); } } } Console.ReadLine(); } } }
위의 코드가 컴파일되고 실행될 때, 다음과 같은 결과가 생성됩니다:
길이: 4.5 너비: 7.5 면적: 33.75 버그 번호: 49 개발자: Nuha Ali 최근 검토: 10/10/2012 备注: 사용되지 않은 변수 버그 번호: 45 개발자: Zara Ali 최근 검토: 12/8/2012 备注: 반환 타입 불일치 버그 번호: 55, Method: GetArea 개발자: Zara Ali 최근 검토: 19/10/2012 备注: 반환 타입 불일치 버그 번호: 56, Method: Display 개발자: Zara Ali 최근 검토: 19/10/2012 备注: