19

"nameof"式は、Visual Studio 2015およびc#6で導入されました。

nameof(C#およびVisual Basicリファレンス)

どうやってそれを使うことができるか。


  • Expressionを使用する厄介な方法があります。 - leppie
  • .NET Frameworkのバージョンは関係ありません。これはC#6の機能です。 VS 2015を使用している場合は、これを使用して任意のバージョンのフレームワークをターゲットにすることができます。 - Charles Mager
  • C#と.NETのバージョンの不一致に関して混乱している人は、を参照してください。stackoverflow.com/questions/28921701/… - tl; dr Roslynは、構文上の糖であるC#6言語機能を、古い.NETバージョンと互換性のあるコードに変換します(たとえば、nameof(parameter)になる"parameter")ただし、VS2015は現在Roslynをサポートしている唯一のIDEであるため、VS2013以前ではこれは機能しません。 - Ian Kemp
  • C#6の「nameof」キーワードでは、任意の型のメンバー名を返すことはできません。このためには、Expression型のパラメータを取るカスタムNameOfメソッド< Func< TSource、TProperty>>まだ必要なようです。 - bugged87

4 답변


23

C#6より前にC#に相当するものについて話しているのであれば、これでプロパティの処理が(ハックな方法で)行われます。おそらくフィールド、メソッドなどを含めるために拡張できます。

public static class TestExtension
{
    public static String nameof<T, TT>(this T obj, Expression<Func<T, TT>> propertyAccessor)
    {
        if (propertyAccessor.Body.NodeType == ExpressionType.MemberAccess)
        {
            var memberExpression = propertyAccessor.Body as MemberExpression;
            if (memberExpression == null)
                return null;
            return memberExpression.Member.Name;
        }
        return null;
    }
}

これをすぐに完成させたので、改善すべきことはたくさんありますが、次のように使用します。

public class myClass
{
    public string myProp { get; set; }
}

var a = new myClass();
var result = a.nameof(b => b.myProp);

結果に「myProp」が含まれる

更新:

より包括的な(それでもまだそれほどきれいではありませんが)

public static class TestExtension
{
    public static String nameof<T, TT>(this Expression<Func<T, TT>> accessor)
    {
        return nameof(accessor.Body);
    }

    public static String nameof<T>(this Expression<Func<T>> accessor)
    {
        return nameof(accessor.Body);
    }

    public static String nameof<T, TT>(this T obj, Expression<Func<T, TT>> propertyAccessor)
    {
        return nameof(propertyAccessor.Body);
    }

    private static String nameof(Expression expression)
    {
        if (expression.NodeType == ExpressionType.MemberAccess)
        {
            var memberExpression = expression as MemberExpression;
            if (memberExpression == null)
                return null;
            return memberExpression.Member.Name;
        }
        return null;
    }
}

静的プロパティ/フィールドへのアクセス

TestExtension.nameof(() => myClass.MyOtherField)

関数内のパラメータにアクセスする:

void func (int a) {
    TestExtension.nameof(() => a);
}


  • dynamic?何のために? - leppie
  • @leppie PropertyExpressionは内部(プライベート?)クラスなので、Member.Nameを取得するためにキャストすることはできません。私は仕事を辞めることにしているだけで、どれが正しいExpressionクラスであるかを正しく理解する時間がありませんでした。でも、気軽に修正してください:) - Rob
  • そのようなクラスはありません(少なくとも.NET 3.5にはない)。MemberExpressionそれがどうなるかです。 - leppie
  • 間違いなくありますPropertyExpressionクラス。行に固執するvar type = propertyAccessor.Body.GetType(); - あなたは正しいがMemberExpressionこの例のために私がキャストしたいものでした。コードを更新します - Rob
  • 私が言ったように、.NET 3.5ではそうではありません。そしておそらくそれが非常に良い理由ですinternalそれ以降のバージョンでは:) - leppie

5

nameOf - で解決されますCompiletime - 逆コンパイルした場合、コンパイラは(Namespace(!)を除いた)クラス名を代わりに定数文字列に変換します。 注意してください。

あなたがクラス名を取得したい場合typeof()またはGetType()で特定の(おそらく派生した)型を取得するRuntimeそしての値を読む

.Name-netのプロパティ< C#6

もっと読むMSDN


  • typeof(T).Name変数の名前ではなく、型の名前を返します。 - Charles W
  • @CharlesWそれで、私は他に何も主張しませんでした…? - Cadburry
  • 私はこれが古いことを知っていますが、nameof元の質問であったタイプ名ではなく、フィールド名またはプロパティ名を取得することです。 - James M

2

私の知る限りでは、魔法の文字列を使わなくてもよい3つの選択肢があります。

  1. の名前これにはVisual Studio 2015が必要です(ただし、他のバージョンの.netフレームワークにコンパイルすることもできます)。

    nameof(this.Property)
    
  2. 式を取り、この記事で見つかったようにプロパティ名を返すメソッドを使用してください」リフレクションを使用してプロパティの文字列名を取得する

    var propertyName = GetPropertyName(  
        () => myObject.AProperty); // returns "AProperty"
    
  3. CallerMemberNameAttribute - (.net framework 4.5でのみ利用可能。元の記事は.net framework 4.0のような古いバージョンで、4.5が含まれていると言っていたため含まれています)このメソッドの引き戻しは現在のメソッドの文字列表現が必要な場合にのみ役に立ちますあなたはで活動しています。

    public string IsChecked  {
       set{
           Console.WriteLine(GetCurrentMemberName()); // prints "IsChecked"
       }
    }
    
    string GetCurrentMemberName([CallerMemberName] string memberName = "")
    {
         return memberName;
    }
    


1

nameof演算子は渡された変数の文字列表現を返すので、nameof(var1)は "var1"を返します。引数の例外のように変数名を文字列として特定する必要があるコードを回避するのに役立ちます。

以前のバージョンでは、リフレクションツリーまたは式ツリーを使用して同様の効果を得ることができました。

リンクされた質問


関連する質問

最近の質問