รับชื่อประเภทที่ไม่มีเนมสเปซเต็ม


293

ฉันมีรหัสต่อไปนี้:

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

แต่

 typeof(T).ToString()

ส่งคืนชื่อเต็มรวมถึงเนมสเปซ

อย่างไรก็ตามมีเพียงรับชื่อคลาส (ไม่มีตัวระบุเนมสเปซหรือไม่)


7
อนึ่งการเขียนstring1 + anything.ToString() + string2ซ้ำซ้อน คอมไพเลอร์แทรกการเรียกร้องให้โดยอัตโนมัติหากคุณทำToString string1 + anything + string2
ทิมโรบินสัน

13
ไม่ให้ฟังดูแย่ แต่มีการตรวจสอบคุณสมบัติของคุณในคุณสมบัติType(ตามที่ส่งกลับมาtypeof(..)) ฉันค่อนข้างแน่ใจว่าคุณคิดออกเอง ...
Peter Lillevold

คำตอบ:


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

5
Nameไม่พิจารณาพารามิเตอร์ประเภท
gregsdennis

73
หรือthis.GetType().Name, this.GetType().FullNameฯลฯ ถ้าจัดการกับอินสแตนซ์
avenmore

1
Nameยังไม่พิจารณาประเภทซ้อนกัน!
Chimpanzee Warlike

33

ลองใช้วิธีนี้เพื่อรับพารามิเตอร์ประเภทสำหรับประเภททั่วไป:

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();
}

อาจไม่ใช่วิธีที่ดีที่สุด (เนื่องจากการเรียกซ้ำ) แต่ใช้งานได้ ผลลัพธ์มีลักษณะดังนี้:

Dictionary<String, Object>

3
คำตอบนี้ควรเป็นคำตอบที่ยอมรับเนื่องจากคำนึงถึงประเภททั่วไปที่อาจชดเชย (ตัวอย่างเช่น Dictionary <int?, int?>)
โอทิส

+1 สำหรับแนวคิด แต่ไม่ชอบการปรับให้เหมาะสมก่อนกำหนดที่ล้มเหลว มันสร้างใหม่ StringBuilderในการโทรซ้ำแต่ละครั้ง (แม้แต่กรณีพื้นฐานเมื่อไม่ได้ใช้) แต่ก็ไม่สนใจstring.Joinแลมบ์ดา LINQ และชั่วคราว เพียงใช้Stringจนกว่าคุณจะรู้ว่ามันเป็นคอขวด / rant
Nigel Touch

1
ไนเจลก็กล่าวว่ามีสิทธิที่อาจไม่ได้เป็นทางออกที่ดีที่สุด :)
gregsdennis

ShortName เป็นชื่อที่สั้นลง :)
วาเลร่า



5

หลังจาก C # 6.0 (รวมถึง) คุณสามารถใช้ชื่อของนิพจน์:

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  

บันทึก! nameofไม่ได้รับประเภทรันไทม์ของวัตถุพื้นฐานเป็นเพียงอาร์กิวเมนต์เวลารวบรวม หากวิธีการยอมรับ IEnumerable แล้วชื่อของเพียงแค่ส่งกลับ "IEnumerable" ในขณะที่วัตถุที่เกิดขึ้นจริงอาจเป็น "รายการ"


3
nameofไม่ส่งคืนชื่อของType
ไนเจล Touch

@NigelTouch ฉันได้ตรวจสอบและnameofส่งคืนชื่อของTypeภาพหน้าจอพร้อมหลักฐาน: prntscr.com/irfk2c
Stas Boyarincev

1
ขออภัยฉันอธิบายไม่ดี สิ่งที่ฉันหมายถึงคือมันไม่ได้รับรันไทม์ของวัตถุต้นแบบTypeเป็นเพียงอาร์กิวเมนต์เวลารวบรวม หากวิธีการยอมรับIEnumerableแล้วnameofเพียงแค่ส่งกลับ "IEnumerable" ในขณะที่วัตถุที่เกิดขึ้นจริงอาจเป็น "รายการ <string>" ไม่คิดว่ามันจะตอบคำถามของ OP
ไนเจล Touch

-2

วิธีที่ดีที่สุดที่จะใช้:

obj.GetType().BaseType.Name

1
โปรดให้คำอธิบายคำตอบของคุณเพื่อให้ชัดเจนยิ่งขึ้นสำหรับผู้ใช้รายอื่น
Stanislav Mekhonoshin

ฉันเคยพบ "GetType (). ชื่อ" เพิ่งเขียนเช่นนั้นในฟังก์ชั่นเสมือน ใครสามารถอธิบายให้ฉันฟังได้ว่าทำไมมันถึงไม่มี obj.GetType () .TypeType.Name? ฉันกำลังเรียน. ฉันเข้าใจวัตถุประสงค์ แต่ไม่ใช่รายละเอียดไวยากรณ์ทั้งหมด ขอบคุณ.
Diego Orellana

ประเภทฐานเกี่ยวข้องกับสิ่งนี้อย่างไร
johnny 5

obj.GetType().BaseType.Nameผลการทดสอบของฉันกลับมา"TypeInfo"ซึ่งไม่ใช่คำตอบที่ต้องการตามที่ฉันคาดหวัง
Nasenbaer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.