C# 반사
반사란 프로그램이 자체 상태나 동작에 액세스하고 이를 감지하고 수정하는 능력을 말합니다.
어셈블리에는 모듈이 포함되고, 모듈에는 멤버가 포함된 유형이 포함됩니다. 리플렉션은 어셈블리, 모듈 및 형식을 캡슐화하는 개체를 제공합니다.
리플렉션을 사용하여 유형의 인스턴스를 동적으로 생성하거나, 기존 객체에 유형을 바인딩하거나, 기존 객체에서 유형을 가져올 수 있습니다. 그런 다음 해당 유형의 메서드를 호출하거나 해당 필드 및 속성에 액세스할 수 있습니다.
장점과 단점
장점:
1. 반사는 프로그램의 유연성과 확장성을 향상시킵니다.
2. 결합을 줄이고 적응 능력을 향상시킵니다.
3. 대상 클래스를 미리 하드코딩하지 않고도 프로그램이 모든 클래스의 객체를 생성하고 제어할 수 있습니다.
단점:
1. 성능 문제: 리플렉션을 사용하는 것은 기본적으로 해석 작업이므로 필드 및 메서드 액세스에 사용할 때 직접 코드보다 훨씬 느립니다. 따라서 리플렉션 메커니즘은 높은 유연성과 확장성을 요구하는 시스템 프레임워크에 주로 사용되며 일반 프로그램에는 권장되지 않습니다.
2. 리플렉션을 사용하면 프로그램의 내부 논리가 흐려집니다. 프로그래머는 소스 코드에서 프로그램의 논리를 확인하기를 원하지만 리플렉션은 소스 코드 기술을 우회하므로 직접 코드가 더 복잡해집니다. .
Reflection의 용도
Reflection의 용도는 다음과 같습니다.
런타임에 속성 정보를 볼 수 있습니다.
컬렉션의 다양한 유형을 검사하고 이러한 유형을 인스턴스화할 수 있습니다.
메서드와 속성의 지연 바인딩을 허용합니다.
런타임에 새로운 유형을 생성한 다음 이러한 유형을 사용하여 일부 작업을 수행할 수 있습니다.
메타데이터 보기
위 장에서 리플렉션을 사용하여 속성 정보를 볼 수 있다고 언급했습니다. 클래스와 관련된 속성을 검색하려면
System.Reflection 클래스의 MemberInfo 개체를 초기화해야 합니다. 이를 위해 다음과 같이 대상 클래스의 객체를 정의할 수 있습니다.
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("Information on the class 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
Instance
이 예에서는 이전 장에서 만든 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("Length: {0}", length); Console.WriteLine("Width: {0}", width); Console.WriteLine("Area: {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("Bug no: {0}", dbi.BugNo); Console.WriteLine("Developer: {0}", dbi.Developer); Console.WriteLine("Last Reviewed: {0}", dbi.LastReview); Console.WriteLine("Remarks: {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("Bug no: {0}, for Method: {1}", dbi.BugNo, m.Name); Console.WriteLine("Developer: {0}", dbi.Developer); Console.WriteLine("Last Reviewed: {0}", dbi.LastReview); Console.WriteLine("Remarks: {0}", dbi.Message); } } } Console.ReadLine(); } } }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 나옵니다.
Length: 4.5 Width: 7.5 Area: 33.75 Bug No: 49 Developer: Nuha Ali Last Reviewed: 10/10/2012 Remarks: Unused variable Bug No: 45 Developer: Zara Ali Last Reviewed: 12/8/2012 Remarks: Return type mismatch Bug No: 55, for Method: GetArea Developer: Zara Ali Last Reviewed: 19/10/2012 Remarks: Return type mismatch Bug No: 56, for Method: Display Developer: Zara Ali Last Reviewed: 19/10/2012 Remarks: