C # Reflection: จะรับการอ้างอิงคลาสจากสตริงได้อย่างไร?


91

ฉันต้องการทำสิ่งนี้ใน C # แต่ฉันไม่รู้ว่า:

ฉันมีสตริงที่มีชื่อคลาส -eg: FooClassและฉันต้องการเรียกใช้เมธอด (คงที่) ในคลาสนี้:

FooClass.MyMethod();

เห็นได้ชัดว่าฉันต้องหาข้อมูลอ้างอิงถึงชั้นเรียนผ่านการไตร่ตรอง แต่อย่างไร?

คำตอบ:


125

คุณจะต้องใช้Type.GetTypeวิธีการ

นี่คือตัวอย่างง่ายๆ:

using System;
using System.Reflection;

class Program
{
    static void Main()
    {
        Type t = Type.GetType("Foo");
        MethodInfo method 
             = t.GetMethod("Bar", BindingFlags.Static | BindingFlags.Public);

        method.Invoke(null, null);
    }
}

class Foo
{
    public static void Bar()
    {
        Console.WriteLine("Bar");
    }
}

ฉันพูดง่ายๆเพราะมันง่ายมากที่จะหาประเภทด้วยวิธีนี้ที่อยู่ในชุดประกอบเดียวกัน โปรดดูคำตอบของจอนสำหรับคำอธิบายที่ละเอียดยิ่งขึ้นเกี่ยวกับสิ่งที่คุณต้องรู้เกี่ยวกับเรื่องนี้ เมื่อคุณเรียกประเภทแล้วตัวอย่างของฉันจะแสดงวิธีเรียกใช้เมธอด


103

คุณสามารถใช้ได้Type.GetType(string)แต่คุณจะต้องรู้ชื่อคลาสแบบเต็มรวมถึงเนมสเปซและหากไม่ได้อยู่ในแอสเซมบลีปัจจุบันหรือ mscorlib คุณจะต้องใช้ชื่อแอสเซมบลีแทน (ตามหลักการใช้Assembly.GetType(typeName)แทน - ฉันพบว่ามันง่ายกว่าในแง่ของการอ้างอิงแอสเซมบลีที่ถูกต้อง!)

ตัวอย่างเช่น:

// "I know String is in the same assembly as Int32..."
Type stringType = typeof(int).Assembly.GetType("System.String");

// "It's in the current assembly"
Type myType = Type.GetType("MyNamespace.MyType");

// "It's in System.Windows.Forms.dll..."
Type formType = Type.GetType ("System.Windows.Forms.Form, " + 
    "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, " + 
    "PublicKeyToken=b77a5c561934e089");

1
+1 เรียบร้อยดี - ฉันได้เพิ่มคำตอบที่แสดงวิธีใช้ประเภทเมื่อคุณได้รับแล้ว ถ้าคุณต้องการดำเนินการต่อและรวมตัวอย่างของฉันเข้ากับคำตอบของคุณและฉันจะลบของฉัน
Andrew Hare

เนื่องจากคุณได้รับการยอมรับแล้วฉันขอแนะนำให้เราทำอีกครั้ง - คุณเพิ่มเนื้อหาของฉันในคำตอบของคุณแล้วฉันจะลบสิ่งนี้ :)
Jon Skeet

4
เพียงเพื่อขยายคำตอบของคุณเพิ่มเติมหากคุณไม่แน่ใจว่าจะส่งอะไรเป็นข้อความไปยังฟังก์ชัน GetType และคุณสามารถเข้าถึงคลาสนี้ได้จากนั้นดู typeof (class) .AssemblyQualifiedName สิ่งนี้จะให้แนวคิดที่ชัดเจน
techExplorer

10

ใช้งานง่าย:

Type typeYouWant = Type.GetType("NamespaceOfType.TypeName, AssemblyName");

ตัวอย่าง:

Type dogClass = Type.GetType("Animals.Dog, Animals");

7

ตอบช้าไปหน่อย แต่ควรใช้เคล็ดลับ

Type myType = Type.GetType("AssemblyQualifiedName");

ชื่อแอสเซมบลีที่ผ่านการรับรองของคุณควรเป็นแบบนี้

"Boom.Bam.Class, Boom.Bam, Version=1.0.0.262, Culture=neutral, PublicKeyToken=e16dba1a3c4385bd"

4
ขอขอบคุณสำหรับการชี้แจงอย่างชัดเจนว่าชื่อที่มีคุณสมบัติเหมาะสมในการชุมนุมควรมีลักษณะอย่างไร
Drew

3

ผ่านType.GetTypeคุณจะได้รับข้อมูลประเภท คุณสามารถใช้คลาสนี้เพื่อรับข้อมูลเมธอดจากนั้นเรียกใช้เมธอด (สำหรับเมธอดแบบคงที่ปล่อยให้พารามิเตอร์แรกเป็นโมฆะ)

คุณอาจต้องใช้ชื่อแอสเซมบลีเพื่อระบุประเภทอย่างถูกต้อง

หากประเภทอยู่ในแอสเซมบลีที่กำลังดำเนินการอยู่หรือใน Mscorlib.dll ก็เพียงพอที่จะระบุชื่อประเภทที่มีคุณสมบัติตามเนมสเปซ


0

เราสามารถใช้

ประเภท GetType ()

เพื่อรับชื่อคลาสและยังสามารถสร้างวัตถุโดยใช้ Activator.CreateInstance(type);

using System;
using System.Reflection;

namespace MyApplication
{
    class Application
    {
        static void Main()
        {
            Type type = Type.GetType("MyApplication.Action");
            if (type == null)
            {
                throw new Exception("Type not found.");
            }
            var instance = Activator.CreateInstance(type);
            //or
            var newClass = System.Reflection.Assembly.GetAssembly(type).CreateInstance("MyApplication.Action");
        }
    }

    public class Action
    {
        public string key { get; set; }
        public string Value { get; set; }
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.