Cách tìm tất cả các kiểu trong một Assembly kế thừa từ một Kiểu cụ thể C #


92

Làm thế nào để bạn có được một bộ sưu tập tất cả các loại kế thừa từ một loại cụ thể khác?

Câu trả lời:


150

Cái gì đó như:

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

Nếu bạn cần xử lý các generic, điều đó sẽ phức tạp hơn một chút (ví dụ: chuyển vào List<>kiểu mở nhưng mong đợi nhận lại kiểu có nguồn gốc từ đó List<int>). Nếu không thì nó rất đơn giản :)

Nếu bạn muốn loại trừ chính loại này, bạn có thể làm như vậy đủ dễ dàng:

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

Lưu ý rằng điều này cũng sẽ cho phép bạn chỉ định một giao diện và tìm tất cả các kiểu triển khai nó, thay vì chỉ làm việc với các lớp như Type.IsSubclassOfhiện tại.


2
Cảm ơn! Tôi đã kết thúc bằng cách sử dụng này. Where (type => type.IsSubclassOf (baseType)). Liệt kê(); }
aceinthehole

@Downvoter tại đây. Bình luận của tôi bị thiếu. Như được chỉ ra bởi aceinthehole, câu trả lời là không chính xác. Tôi đã thêm câu trả lời chính xác vì tôi bỏ lỡ nhận xét của aces cho đến khi tôi thấy mã không hoạt động. Giáng sinh vui vẻ.
Tim Murphy

@Tim: Không sai, hơi khác một chút. IsAssignableFromcũng nên hoạt động. Đặc biệt, phiên bản của tôi cũng đối phó với các giao diện. Bạn đã kiểm tra mã của tôi? Trường hợp nào câu trả lời của tôi không thành công?
Jon Skeet

1
@Jon. Khá đúng phương pháp của bạn xử lý các giao diện. Tôi là một lập trình viên VB, chúng tôi kế thừa các lớp và triển khai các giao diện. Điều này có khác trong C # không? Tôi hỏi vì câu hỏi, như tôi yêu cầu, muốn các kiểu kế thừa một kiểu không triển khai một kiểu.
Tim Murphy

2
@Tim: Trong C #, chúng tôi chỉ sử dụng ":" cho cả hai ... nhưng tôi thường coi các giao diện là một phần của hệ thống phân cấp kế thừa của một kiểu.
Jon Skeet

27

Phương thức sau sẽ nhận được một tập hợp các kiểu kế thừa một kiểu.

C #

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

Nếu bạn cần bao gồm các loại triển khai giao diện, hãy xem câu trả lời của @Jon Skeet.


1

Bạn phải liệt kê tất cả các loại và kiểm tra từng loại nếu nó kế thừa loại mà bạn đang tìm kiếm.

Một số mã như mã trong câu hỏi này có thể hữu ích cho bạn.


1

Cân nhắc sử dụng phương pháp này (được viết cho 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();
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.