Csharp/CSharp Tutorial/Reflection/Type

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

A second form of GetMethods() lets you specify various flags that filter the methods that are retrieved.

It has this general form:


<source lang="csharp">MethodInfo[ ] GetMethods(BindingFlags criteria)</source>

This version obtains only those methods that match the criteria.

BindingFlags is an enumeration.

Its most commonly used values are shown here:

Value Meaning DeclaredOnly Retrieves only those methods defined by the specified class. Inherited methods are not included. Instance Retrieves instance methods. NonPublic Retrieves nonpublic methods. Public Retrieves public methods. Static Retrieves static methods.

Cast And OfType

<source lang="csharp">using System; using System.Collections; using System.Linq; using System.ruponentModel;

   class MainClass
   {
       static void Main()
       {
           ArrayList list = new ArrayList { "First", "Second", "Third"};
           var strings = list.Cast<string>();
           foreach (string item in strings)
           {
               Console.WriteLine(item);
           }
           list = new ArrayList { 1, "not an int", 2, 3};
           var ints = list.OfType<int>();
           foreach (int item in ints)
           {
               Console.WriteLine(item);
           }
       }
   }</source>

Commonly used methods defined by Type:

Method Purpose ConstructorInfo[ ] GetConstructors() Obtains a list of the constructors. EventInfo[ ] GetEvents() Obtains a list of events. FieldInfo[ ] GetFields() Obtains a list of the fields. MemberInfo[ ] GetMembers() Obtains a list of the members. MethodInfo[ ] GetMethods() Obtains a list of methods. PropertyInfo[ ] GetProperties() Obtains a list of properties.

Here are several commonly used, read-only properties defined by Type:

Property Purpose Assembly Assembly Obtains the assembly. TypeAttributes Attributes Obtains the attributes. Type BaseType Obtains the immediate base type. string FullName Obtains the complete name. bool IsAbstract Is abstract. bool isArray Is an array. bool IsClass Is a class. bool IsEnum Is an enumeration. string Namespace Obtains the namespace.

Create StringBuilder

<source lang="csharp">using System; using System.Text; using System.Reflection; class MainClass {

   public static void Main ()
   {
       Type type = typeof(StringBuilder);
       Type[] argTypes = new Type[] { typeof(System.String), typeof(System.Int32) };
       ConstructorInfo cInfo = type.GetConstructor(argTypes);
       object[] argVals = new object[] { "Some string", 30 };
       // Create the object and cast it to StringBuilder.
       StringBuilder sb = (StringBuilder)cInfo.Invoke(argVals);
       Console.WriteLine(sb);
   }

}</source>

Some string

Dynamically constructing types

<source lang="csharp">using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Reflection; using System.Reflection.Emit; public class MainClass {

   public static void Main()
   {
       Type listType = typeof(List<>);
       Type listOfIntType = listType.MakeGenericType(typeof(int));
       Console.WriteLine(listOfIntType.FullName);
   }

}</source>

System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicK
eyToken=b77a5c561934e089]]

Get all methods from a Type

<source lang="csharp">using System; using System.Reflection; class MyClass {

  public int Field1;
  public int Field2;
  public void Method1() { }
  public int  Method2() { return 1; }

} class MainClass {

  static void Main()
  {
     Type t = typeof(MyClass);
     MethodInfo[] mi = t.GetMethods();
     foreach (MethodInfo m in mi)
        Console.WriteLine("Method: {0}", m.Name);
  }

}</source>

Method: Method1
Method: Method2
Method: GetType
Method: ToString
Method: Equals
Method: GetHashCode

Get BaseType, Name, FullName and Namespace for a type

<source lang="csharp">using System; class MainClass {

 static void Main(string[] args)
 {
   Object cls1 = new Object();
   System.String cls2 = "Test String" ;
   Type type1 = cls1.GetType();
   Type type2 = cls2.GetType();
   // Object class output
   Console.WriteLine(type1.BaseType);
   Console.WriteLine(type1.Name);
   Console.WriteLine(type1.FullName);
   Console.WriteLine(type1.Namespace);
   // string output
   Console.WriteLine(type2.BaseType);
   Console.WriteLine(type2.Name);
   Console.WriteLine(type2.FullName);
   Console.WriteLine(type2.Namespace);
 } 

}</source>

Object
System.Object
System
System.Object
String
System.String
System

Get/set property using invoke member

<source lang="csharp">using System; using System.Reflection; using System.Windows.Forms; public class Class1 {

   static void Main(string[] args)
   {
       Type type = typeof(MyClass);
       object o = Activator.CreateInstance(type);
       type.InvokeMember("Text", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.Public, null, o, new object[] { "Windows Developer Magazine" });
       string text = (string)type.InvokeMember("Text", BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public, null, o, new object[] { });
       Console.WriteLine(text);
   }
   private static void OnChanged(object sender, System.EventArgs e)
   {
       Console.WriteLine(((MyClass)sender).Text);
   }

} public class MyClass {

   private string text;
   public string Text
   {
       get { return text; }
       set
       {
           text = value;
           OnChanged();
       }
   }
   private void OnChanged()
   {
       if (Changed != null)
           Changed(this, System.EventArgs.Empty);
   }
   public event EventHandler Changed;

}</source>

Get the Type representation: object

<source lang="csharp">using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Reflection; using System.Reflection.Emit; public class MainClass {

   public static void Main()
   {
       Type typeInfo = typeof(object);
       MethodInfo methInfo = typeInfo.GetMethod("ToString");
       Console.WriteLine("Info: {0}", methInfo);
   }

}</source>

Info: System.String ToString()

Getting generic type definition information

<source lang="csharp">using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Reflection; using System.Reflection.Emit; public class MainClass {

   public static void Main()
   {
       Console.WriteLine(typeof(List<>).Equals(typeof(List<int>).GetGenericTypeDefinition()));
   }

}</source>

True

Get Type with typeof

<source lang="csharp">using System; using System.Reflection; using System.Globalization;

 class Class1
 {
   DateTime[] dateTimes = new DateTime[10];
   public DateTime this[int index]
   {
     get{ return dateTimes[index]; }
     set{ dateTimes[index] = value;}
   }
   
   
   private DateTime dateOfBirth;
   public DateTime DateOfBirth
   {
       get{ return dateOfBirth; }
       set{ dateOfBirth = value; }
   }
     
   public void Test()
   {
     Console.WriteLine("Test method called");
   }
   
   
   private string field;
   
   public string Property
   { 
     get{ return field; }
     set{ field = value; }
   }
   
 }
   class MainClass{
   
   static void Main(string[] args)
   {
     Type type = typeof(Class1);
     Console.WriteLine(type.FullName);
     
     type = Type.GetType("Class1");
     Console.WriteLine(type.Namespace);
   }
   }</source>

Is object a type

<source lang="csharp">using System; using System.IO; class MainClass {

   public static void Main() 
   {
       Object someObject = new StringReader("This is a StringReader");
       
       if (IsType(someObject, "System.IO.TextReader")) 
       {
           Console.WriteLine("GetType: someObject is a TextReader");
       }
   }
   public static bool IsType(object obj, string type) 
   {
       Type t = Type.GetType(type, true, true);
       return t == obj.GetType() || obj.GetType().IsSubclassOf(t);
   }
   

}</source>

GetType: someObject is a TextReader

Obtain the handles: object

<source lang="csharp">using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Reflection; using System.Reflection.Emit; public class MainClass {

   public static void Main()
   {
       Type typeInfo = typeof(object);
       MethodInfo methInfo = typeInfo.GetMethod("ToString");
       RuntimeTypeHandle typeHandle = typeInfo.TypeHandle;
       RuntimeMethodHandle methHandle = methInfo.MethodHandle;
       Console.WriteLine("Handle: {0}", methHandle);
   }

}</source>

Handle: System.RuntimeMethodHandle

Obtain type information using the Object.GetType method

<source lang="csharp">using System; using System.Text; class MainClass {

   public static void Main()
   {

       StringBuilder sb = new StringBuilder();
       Type t6 = sb.GetType();
   }

}</source>

Obtain type information using the Type.GetType method(Case insensitive, throw TypeLoadException if not found)

<source lang="csharp">using System; using System.Text; class MainClass {

   public static void Main()
   {
       Type t4 = Type.GetType("system.string", true, true);
   }

}</source>

Obtain type information using the Type.GetType method(Case sensitive, return null if not found).

<source lang="csharp">using System; using System.Text; class MainClass {

   public static void Main()
   {
       Type t2 = Type.GetType("System.String");
   }

}</source>

Obtain type information using the Type.GetType method(Case sensitive, throw TypeLoadException if not found)

<source lang="csharp">using System; using System.Text; class MainClass {

   public static void Main()
   {
       Type t3 = Type.GetType("System.String", true);
   }

}</source>

Open and constructed generic types

<source lang="csharp">using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Reflection; using System.Reflection.Emit; public class MainClass {

   public static void Main()
   {
       Type listType = typeof(List<>);
       Console.WriteLine("List<>: {0}, {1}",listType.IsGenericType, listType.ContainsGenericParameters);
       Type listIntType = typeof(List<int>);
       Console.WriteLine("List<int>: {0}, {1}",listIntType.IsGenericType, listIntType.ContainsGenericParameters);
   }

}</source>

List<>: True, True
List<int>: True, False

Reflection

System.Type is derived from an abstract class called System.Reflection.MemberInfo.

MemberInfo defines the following abstract, read-only properties:

Return Type Method Name Meanings Type DeclaringType The type of the class or interface in which the member is declared. MemberTypes MemberType The type of the member. string Name The name of the type. Type ReflectedType The type of the object being reflected.

MemberTypes is an enumeration:

  1. MemberTypes.Constructor
  2. MemberTypes.Method
  3. MemberTypes.Field
  4. MemberTypes.Event
  5. MemberTypes.Property

Type: FullName, BaseType, IsAbstract, IsCOMObject, IsSealed, IsClass

<source lang="csharp">using System; using System.Reflection; public interface IFaceOne {

 void MethodA();

} public interface IFaceTwo {

 void MethodB();

} public class MyClass: IFaceOne, IFaceTwo {

 public enum MyNestedEnum{}
 
 public int myIntField;
 public string myStringField;
 public void myMethod(int p1, string p2)
 {
 }
 public int MyProp
 {
   get { return myIntField; }
   set { myIntField = value; }
 }
 void IFaceOne.MethodA(){}
 void IFaceTwo.MethodB(){}

} public class MainClass {

 public static void Main(string[] args)
 {
   MyClass f = new MyClass();
   Type t = f.GetType();
   Console.WriteLine("Full name is: {0}", t.FullName);
   Console.WriteLine("Base is: {0}", t.BaseType);
   Console.WriteLine("Is it abstract? {0}", t.IsAbstract);
   Console.WriteLine("Is it a COM object? {0}", t.IsCOMObject);
   Console.WriteLine("Is it sealed? {0}", t.IsSealed);
   Console.WriteLine("Is it a class? {0}", t.IsClass);
   
 }

}</source>

Full name is: MyClass
Base is: System.Object
Is it abstract? False
Is it a COM object? False
Is it sealed? False
Is it a class? True

type identity

Runtime type ID is the mechanism that lets you identify a type during the execution of a program.

Reflection enables you to obtain information about a type.


<source lang="csharp">using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text;

public class MainClass {

   public static void Main()
   {
       string s = "A string";
       Type t = s.GetType();
       Console.WriteLine(t.Name);              
       Console.WriteLine(t.Namespace);         
       Console.WriteLine(t.IsPublic);          
       Console.WriteLine(t == typeof(string)); 
   }

}</source>

String
System
True
True