3

変数名を取得する方法を探しているので、必要に応じてハードコードされた宣言を使用する必要はありません (プロパティ名など)。

私はそれが可能だとはほとんど信じていません。誰かが解決策を持っているかもしれません。注: 変数でなくても、プロパティも動きます。

'Pseudo:
Module Module1

    Sub Main()
        Dim variable = "asdf"
        Dim contact As New Contact

        Dim v1 = GetVariableName(variable) 'returns variable
        Dim v2 = GetVariableName(contact.Name) 'returns Name

    End Sub

    Class Contact
        Public ReadOnly Property Name()
            Get
                Return Nothing
            End Get
        End Property
    End Class

    Public Function GetVariableName(variable As Object) As String
        ':}
    End Function

End Module

回答は、VB または C# で歓迎されます。

4

4 に答える 4

5

@Abraham Pinzur; リンク先の記事の別のリンクをたどると、このスニペットが提供されます。

static void Main(string[] args)
{
Console.WriteLine("Name is '{0}'", GetName(new {args}));
Console.ReadLine();
}

static string GetName<T>(T item) where T : class
{
var properties = typeof(T).GetProperties();
return properties[0].Name;
}

これは「名前は'args'」を生成します。Rinatのメソッドは、C#コンパイラによって生成されたプロパティ名を利用して、式に匿名型を生成しますnew{args}。完全な記事はここにあります:http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html

- 編集 -

Rinatの記事をさらに読んだ後、これは、式ツリーを作成し、ツリーまたはそれに含まれるILのいずれかを参照することによっても実行できます。基本的にはリンク先の記事を読んでください!

于 2009-09-06T21:10:38.757 に答える
5

ああ、簡単な解決策があります。ここでは式ツリーを使用します。これは例です。C#でニーズに合わせてください

string GetPropertyName<T>(Expression<Func<T>> property)
{
    MemberExpression ex = (MemberExpression)property.Body;
    string propertyName = ex.Member.Name;
    return propertyName;
}

今、あなたはすることができます

String example = null;
String propertyName = GetPropertyName(()=>example.Length);
//propertyName == "Length"

それを初めて見たとき、それは啓示でした!;)

于 2009-09-06T21:41:47.503 に答える
3

Rinat Abdullin は、匿名メソッド (またはラムダ式) から IL を解析することで、このようなことを行っています。彼の完全なコードはこちらです。

したがって、例は次のようになります。

class Program
{
    static void Main (string[] args)
    {
        var variable = "asdf";

        var v1 = GetVariableName(() => variable);  // returns "variable"
    }

    static string GetVariableName (Func<object> variable)
    {   // Again, credit to Mr. Abdullin ...
        var il = variable.Method.GetMethodBody().GetILAsByteArray();
        var fieldHandle = BitConverter.ToInt32(il,2);
        var field = variable.Target.GetType()
                .Module.ResolveField(fieldHandle);
        return field.Name;
    }
}

contact.Nameただし、これは 2 番目のケース ( --> )には直接適用されません"Name"

于 2009-09-06T20:40:33.820 に答える
2

それは可能ではありません。この例のメソッドに送信されるのは、変数自体ではなく、変数に含まれる参照のコピーのみです。

このメソッドは、メンバー変数間の参照のために存在するすべてのオブジェクトをスキャンできますが、それは、変数がクラスメンバーである場合にのみ実行できます。ローカル変数はスタック上にのみ存在するため、その方法で到達することはできません。また、同じ参照が複数の変数に存在する場合、メソッドはそれらのどれが使用されたかを判別できません。

あなたの例では、Nameプロパティはnull参照を返しますが、それがどこから来たのかを知ることはもちろん不可能です。

変数が値型の場合、ヒープ上の新しいオブジェクト内にボックス化されます。ボックス化されたオブジェクトへの唯一の参照はメソッドに送信されるものであり、ボックス化されたオブジェクトには元のオブジェクトへの参照がないため、どの変数がボックス化されたかを知る方法はありません。

于 2009-09-06T21:03:13.693 に答える