完全な名前空間なしで型名を取得する


293

私は次のコードを持っています:

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

だが

 typeof(T).ToString()

名前空間を含むフルネームを返します

とにかくクラス名を取得するだけですか(名前空間修飾子なしで?)


7
ちなみに、書き込みstring1 + anything.ToString() + string2は冗長です。コンパイラは、呼び出しをToString自動的に挿入しますstring1 + anything + string2
Tim Robinson

13
厳しく聞こえるわけではありませんが、Typeインスタンスで使用できるプロパティ(によって返されるものtypeof(..))を調べたら、自分でこれを理解していると思います...
Peter Lillevold

回答:



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?>)を適切に考慮しているため、受け入れられる答えになるはずです。
Otis

コンセプトの+1。しかし、失敗した時期尚早の最適化は嫌いです。再帰呼び出しごとに(未使用の基本ケースでさえ)新規 に作成しますがStringBuilderstring.Join一時的なLINQラムダは無視します。ちょうど使用Stringあなたがするまで知っている、それがボトルネックです。/ rant
Nigel Touch

1
ナイジェル、それはたぶん最善の解決策ではない、とすぐに言っています:)
gregsdennis '05年

ShortNameは短い名前です:)
Valera



5

C#6.0(を含む)以降では、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  

注意!nameof基本となるオブジェクトのランタイムTypeを取得するのではなく、単にコンパイル時の引数です。メソッドがIEnumerableを受け入れる場合、nameofは単に「IEnumerable」を返しますが、実際のオブジェクトは「List」である可能性があります。


3
nameofの名前を返さないType
Nigel Touch

@NigelTouch確認し、証明のあるスクリーンショットのnameof名前を返しますTypeprntscr.com/irfk2c
Stas Boyarincev

1
申し訳ありませんが、よく説明できませんでした。つまり、基になるオブジェクトのランタイムを取得せずType、単なるコンパイル時の引数です。この方法は、受け入れた場合IEnumerable、その後nameof、実際のオブジェクトは可能性があり、一方、単に「リスト<文字列>」、「IEnumerableを」を返します。それはOPの質問に答えるとは思わない。
Nigel Touch

-2

使用する最良の方法:

obj.GetType().BaseType.Name

1
他のユーザーにわかりやすくするために、回答に説明を入力してください。
Stanislav Mekhonoshin 2017年

私はかつて「GetType()。Name」を仮想関数内にそのように書かれたことを見つけました。なぜobj.GetType()。BaseType.Nameがないのか誰かに説明できますか?勉強中です。目的は理解していますが、構文の詳細はすべてではありません。ありがとうございました。
Diego Orellana

基本タイプはこれとどのような関係がありますか?
ジョニー

私のテストobj.GetType().BaseType.Name"TypeInfo"期待どおりの望ましいソリューションではない結果を返します。
Nasenbaer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.