3

I have a class

public class MyCoolProp
{
    public string FullName {get;set;}
}

and in another Class i have this as Property:

public class MyMainClass
{
    public MyCoolProp coolprop {get;set;}

    public void DoSomething()
    {
        MessageBox.Show(nameof(coolprop.FullName));
    }
}

The Actual Result is: "Fullname"

But i want a combination like this: "coolprop.FullName"

i dont want to do something like this:

nameof(coolprop) + "." + nameof(coolprop.FullName);

Maybe its possible in an extension?

If i rename the Property "coolprop" the output should also have the new name

2
  • I believe this might be a duplicate of this which basically says you cannot. Commented Jun 2, 2022 at 9:46
  • 1
    @PhilMasteG: That was back in 2016 - for some cases, the C# 10 feature of CallerArgumentExpression may be useful. Commented Jun 2, 2022 at 9:50

3 Answers 3

8

Depending on exactly what you want to do, you might be able to use CallerArgumentExpressionAttribute. That does mean you need to be willing to actually evaluate the property as well, even if you don't use it.

Note that this requires a C# 10 compiler.

Here's a complete example:

using System.Runtime.CompilerServices;

public class MyCoolProp
{
    public string FullName { get; set; }
}

class Program
{
    static MyCoolProp CoolProp { get; set; }

    static void Main()
    {
        CoolProp = new MyCoolProp { FullName = "Test" };
        WriteTextAndExpression(CoolProp.FullName);
    }

    static void WriteTextAndExpression(string text,
        [CallerArgumentExpression("text")] string expression = null)
    {
        Console.WriteLine($"{expression} = {text}");
    }
}

Output: CoolProp.FullName = Test

Sign up to request clarification or add additional context in comments.

Comments

4

Source: get name of a variable or parameter (modified a bit adjusted with your case)

You can use what System.Linq.Expression provides code example:

using System.Linq.Expression
class Program
{
    public static MyCoolProp coolProp { get; set; }
    static void Main(string[] args)
    {
        coolProp = new MyCoolProp() { FullName = "John" };
        DoSomething();
    }

    public static string GetMemberName<T>(Expression<Func<T>> memberExpression)
    {
        MemberExpression expressionBody = (MemberExpression)memberExpression.Body;
        return expressionBody.ToString();
    }

    public static void DoSomething()
    {
        string prop = GetMemberName(() => coolProp.FullName);
        Console.WriteLine(prop);
    }

}

public class MyCoolProp
{
    public string FullName { get; set; }
}

the GetMemberName method will return the namespace, class name, object name, and variable name (depends where the method is being called)

Output: Program.coolProp.FullName

Comments

0

Inspired by @kim's linq expression solution, here's an implementation that is hopefully a closer match to the nameof(XXX.YYY) that the OP was wanting. In particular..

  • Doesn't require an object instance, i.e. works directly against the types similar to nameof()
  • Also, it doesn't rely on ToString() to generate the full name, i.e. hopefully less brittle
public static string Of<T>(Expression<Func<T, object>> expression)
{
    static MemberExpression GetMemberExpression(Expression expression) =>
        expression as MemberExpression ?? (expression as UnaryExpression)?.Operand as MemberExpression;

    var names = new Stack<string>();
    var memberExpression = GetMemberExpression(expression.Body);

    while (memberExpression != null)
    {
        names.Push(memberExpression.Member.Name);
        memberExpression = GetMemberExpression(memberExpression.Expression);
    }

    names.Push(expression.Parameters.First().Type.Name);

    return string.Join(".", names);
}

Usage..

public class MyCoolProp
{
    public string FullName {get;set;}
    public CoolerProp AnotherProp { get; set; }
}

public class CoolerProp
{
    public string Name {get;set;}
}

[Test]
public void Test()
{
    Assert.That(Name.Of<MyCoolProp>(x => x.FullName), Is.EqualTo("MyCoolProp.FullName"));
    Assert.That(Name.Of<MyCoolProp>(x => x.AnotherProp.Name), Is.EqualTo("MyCoolProp.AnotherProp.Name"));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.