Nhận tên loại không có không gian tên đầy đủ


293

Tôi có đoạn mã sau:

return "[Inserted new " + typeof(T).ToString() + "]";

Nhưng

 typeof(T).ToString()

trả về tên đầy đủ bao gồm cả không gian tên

Có cách nào để lấy tên lớp (không có bất kỳ vòng loại không gian tên nào không?)


7
Ngẫu nhiên, viết string1 + anything.ToString() + string2là dư thừa. Trình biên dịch sẽ chèn cuộc gọi ToStringtự động nếu bạn thực hiện string1 + anything + string2.
Tim Robinson

13
không nghe có vẻ gay gắt nhưng, bạn đã kiểm tra các thuộc tính có sẵn trong Typetrường hợp (như được trả lại bởi typeof(..)) Tôi khá chắc chắn rằng bạn sẽ tự mình tìm ra điều này ...
Peter Lillevold

Câu trả lời:


530
typeof(T).Name // class name, no namespace
typeof(T).FullName // namespace and class name
typeof(T).Namespace // namespace, no class name

5
Namekhông xem xét các tham số loại.
gregsdennis

73
Hoặc this.GetType().Name, this.GetType().FullNamevv nếu xử lý các trường hợp.
avenmore

1
Namecũng không xem xét các loại lồng nhau!
Tinh tinh hiếu chiến

33

Hãy thử điều này để có được các tham số loại cho các loại chung:

public static string CSharpName(this Type type)
{
    var sb = new StringBuilder();
    var name = type.Name;
    if (!type.IsGenericType) return name;
    sb.Append(name.Substring(0, name.IndexOf('`')));
    sb.Append("<");
    sb.Append(string.Join(", ", type.GetGenericArguments()
                                    .Select(t => t.CSharpName())));
    sb.Append(">");
    return sb.ToString();
}

Có thể không phải là giải pháp tốt nhất (do đệ quy), nhưng nó hoạt động. Đầu ra trông như:

Dictionary<String, Object>

3
Đây phải là câu trả lời được chấp nhận vì nó xem xét đúng các loại chung có thể lặp lại (ví dụ: Từ điển <int ?, Int?>).
Otis

+1 cho khái niệm. Nhưng không thích tối ưu hóa sớm thất bại. Nó tạo ra một điểm mới StringBuilder trong mỗi cuộc gọi đệ quy (ngay cả trường hợp cơ sở khi không sử dụng), nhưng bỏ qua string.Joinlambda tạm thời và LINQ. Chỉ cần sử dụng Stringcho đến khi bạn biết đó là một nút cổ chai. / rant
Nigel Touch

1
Nigel, nó nói đúng đó có lẽ không phải là giải pháp tốt nhất :)
gregsdennis

ShortName là một tên ngắn hơn :)
Valera



5

Sau C # 6.0 (bao gồm), bạn có thể sử dụng biểu thức nameof :

using Stuff = Some.Cool.Functionality  
class C {  
    static int Method1 (string x, int y) {}  
    static int Method1 (string x, string y) {}  
    int Method2 (int z) {}  
    string f<T>() => nameof(T);  
}  

var c = new C()  

nameof(C) -> "C"  
nameof(C.Method1) -> "Method1"   
nameof(C.Method2) -> "Method2"  
nameof(c.Method1) -> "Method1"   
nameof(c.Method2) -> "Method2"  
nameof(z) -> "z" // inside of Method2 ok, inside Method1 is a compiler error  
nameof(Stuff) = "Stuff"  
nameof(T) -> "T" // works inside of method but not in attributes on the method  
nameof(f) -> f  
nameof(f<T>) -> syntax error  
nameof(f<>) -> syntax error  
nameof(Method2()) -> error This expression does not have a name  

Ghi chú! nameofkhông nhận được Kiểu thời gian chạy của đối tượng cơ bản, nó chỉ là đối số thời gian biên dịch. Nếu một phương thức chấp nhận IEnumerable thì nameof chỉ đơn giản trả về "IEnumerable", trong khi đối tượng thực tế có thể là "Danh sách".


3
nameofkhông trả lại tên củaType
Nigel Touch

@NigelTouch Tôi đã kiểm tra và nameoftrả lại tên của Typeảnh chụp màn hình với bằng chứng: prntscr.com/irfk2c
Stas Boyarincev 15/03/18

1
Xin lỗi, tôi đã không giải thích tốt. Ý tôi là nó không nhận được thời gian chạy của đối tượng cơ bản Type, nó chỉ là đối số thời gian biên dịch. Nếu một phương thức chấp nhận IEnumerablethì nameofchỉ cần trả về "IEnumerable", trong khi đối tượng thực tế có thể là "Danh sách <chuỗi>". Nó không nghĩ rằng nó trả lời câu hỏi của OP.
Nigel Touch

-2

cách tốt nhất để sử dụng:

obj.GetType().BaseType.Name

1
Vui lòng cung cấp một số giải thích cho câu trả lời của bạn, để làm cho nó rõ ràng hơn cho những người dùng khác.
Stanislav Mekhonoshin

Tôi đã từng tìm thấy "GetType (). Name" chỉ được viết như thế bên trong một hàm ảo. Ai đó có thể giải thích cho tôi tại sao nó không có obj.GetType (). BaseType.Name không? Tôi đang học. Tôi hiểu mục đích nhưng không phải tất cả các chi tiết cú pháp. Cảm ơn bạn.
Diego Orellana

Loại cơ sở phải làm gì với điều này?
ngày 5

Thử nghiệm của tôi obj.GetType().BaseType.Nametrả về "TypeInfo"đó không phải là giải pháp mong muốn như tôi mong đợi.
Nasenbaer
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.