วิธีค้นหาทุกประเภทในแอสเซมบลีที่สืบทอดมาจาก Type C # เฉพาะ


คำตอบ:


154

สิ่งที่ต้องการ:

public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
    return assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t));
}

หากคุณต้องการจัดการกับยาชื่อสามัญสิ่งนั้นจะค่อนข้างยุ่งยากกว่า (เช่นการส่งในList<>ประเภทเปิดแต่คาดหวังว่าจะได้รับประเภทที่มาจากList<int>) อย่างอื่นมันง่ายมาก :)

หากคุณต้องการแยกประเภทออกคุณสามารถทำได้อย่างง่ายดายพอ:

public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
    return assembly.GetTypes().Where(t => t != baseType && 
                                          baseType.IsAssignableFrom(t));
}

โปรดทราบว่าสิ่งนี้จะช่วยให้คุณสามารถระบุอินเทอร์เฟซและค้นหาทุกประเภทที่ใช้งานได้แทนที่จะทำงานกับคลาสเหมือนที่Type.IsSubclassOfทำ


2
ขอบคุณ! ฉันลงเอยด้วยการใช้คำขอบคุณนี้ - ฉันลงเอยด้วยการใช้รายการแบบคงที่สาธารณะ <Type> GetAllSubclassesOf (Type baseType) {return Assembly.GetAssembly (baseType) .GetTypes () โดยที่ (type => type.IsSubclassOf (baseType)) ToList (); }
aceinthehole

@Downvoter ที่นี่. ความคิดเห็นของฉันหายไป ตามที่ระบุโดย aceinthehole คำตอบไม่ถูกต้อง ฉันได้เพิ่มคำตอบที่ถูกต้องเนื่องจากฉันพลาดความคิดเห็นของเอซจนกว่าฉันจะพบว่ารหัสใช้งานไม่ได้ สุขสันต์วันคริสต์มาส.
Tim Murphy

@ ทิม: ไม่ถูกต้องต่างกันเล็กน้อย IsAssignableFromควรทำงานเช่นกัน โดยเฉพาะเวอร์ชันของฉัน copes กับอินเทอร์เฟซเช่นกัน คุณทดสอบรหัสของฉันหรือไม่? คำตอบของฉันล้มเหลวในกรณีใด
Jon Skeet

1
@ จอน. วิธีการจัดการอินเทอร์เฟซของคุณค่อนข้างถูกต้อง ฉันเป็นโปรแกรมเมอร์ VB เราสืบทอดคลาสและใช้อินเทอร์เฟซ C # ต่างกันไหม ฉันถามเพราะคำถามตามที่ฉันต้องการต้องการประเภทที่สืบทอดประเภทที่ไม่ใช้ประเภท
Tim Murphy

2
@Tim: ใน C # เราใช้แค่ ":" สำหรับทั้งสอง ... แต่โดยทั่วไปฉันจะถือว่าอินเทอร์เฟซเป็นส่วนหนึ่งของลำดับชั้นการสืบทอดของประเภท
Jon Skeet

27

วิธีการต่อไปนี้จะได้รับคอลเลกชันประเภทที่สืบทอดประเภท

ค#

public IEnumerable<Type> FindSubClassesOf<TBaseType>()
{   
    var baseType = typeof(TBaseType);
    var assembly = baseType.Assembly;

    return assembly.GetTypes().Where(t => t.IsSubclassOf(baseType));
}

VB.NET

Public Function FindSubClasses(Of TBaseType)() As IEnumerable(Of Type)

    Dim baseType = GetType(TBaseType)
    Dim assembly = baseType.Assembly

    Return From t In assembly.GetTypes() 
           Where t.IsSubClassOf(baseType) 
           Select t

End Function

หากคุณต้องการรวมประเภทที่ใช้อินเทอร์เฟซโปรดดูคำตอบของ @Jon Skeet


1

คุณต้องแจกแจงทุกประเภทและตรวจสอบว่าสืบทอดประเภทที่คุณกำลังมองหาหรือไม่

รหัสบางอย่างเช่นในคำถามนี้อาจเป็นประโยชน์สำหรับคุณ


1

ลองใช้วิธีนี้ (เขียนสำหรับ PCL):

public IEnumerable<Type> FindDerivedTypes( Assembly assembly, Type baseType )
{
        TypeInfo baseTypeInfo = baseType.GetTypeInfo();
        bool isClass = baseTypeInfo.IsClass, isInterface = baseTypeInfo.IsInterface;

        return
            from type in assembly.DefinedTypes
            where isClass ? type.IsSubclassOf( baseType ) :
                  isInterface ? type.ImplementedInterfaces.Contains( baseTypeInfo.AsType() ) : false
            select type.AsType();
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.