1

I want to use nameof in order to get the name of a property.

The following work:

DerivedClass EC = baseClassObj as DerivedClass;
nameof(EC.propertyX)

but this doesn't work:

nameof((baseClassObj as DerivedClass).propertyX)

with the compile error of:

Sub-expression cannot be used in an argument to nameof

BTW, also this doesn't work:

nameof(((baseClassObj)DerivedClass).propertyX)

Can someone explain this casting + nameof problem?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Yuval Levy
  • 2,397
  • 10
  • 44
  • 73
  • 3
    There is no other explanation than finding the language specification for you or looking at the documentation. It's simply not supported. – Tim Schmelter Dec 14 '17 at 13:02
  • The error explains it all. No sub-expressions are allowed as arguments to `nameof`. Try storing `(baseClassObj as DerivedClass)` into a variable, and use that in the nameof argument. – EvilTak Dec 14 '17 at 13:03
  • 1
    As RATM used to say : "Casting then the nameof". And now you do what they told ya – Drag and Drop Dec 14 '17 at 13:03
  • It's the same reason why you can not use every expression you want in a constant: the compiler needs to be able to evaluate the expression at compile time. That means you are restricted to operations the compiler can actually do. – Sefe Dec 14 '17 at 13:07
  • Possible duplicate of [Is nameof() evaluated at compile-time?](https://stackoverflow.com/questions/26573102/is-nameof-evaluated-at-compile-time) – FrankM Dec 14 '17 at 13:12

3 Answers3

4

nameof is a compile time thing and therefore static. To get what you want, just use nameof(DerivedClass.PropertyX):

class BaseClass
{
}

class DerivedClass : BaseClass
{
    public string PropertyX { get; set; }
}

static class UsePropertyName
{
    public static string GetPropertyName(BaseClass classInstance)
    {
        //Instance not actually used.
        return nameof(DerivedClass.PropertyX);
    }
}
Adam Brown
  • 1,667
  • 7
  • 9
0

nameof works basically as a preprocessed macro. Before compile time it will be replaced by the actual name of the parameter, from there on it is like a "constant string" in the assembly.

The argument expression identifies a code definition, but it is never evaluated. see here: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/nameof

FrankM
  • 541
  • 3
  • 15
-1

As far as I know, the nameof() works with reflection based on the expression provided in nameof(). Therefore, the engine obviously has problems to "decompile" the expression if it's not "simple expression".

You might be interested in creating some extension method that will take baseClassObj as DerivedClass as parameter and return the result of nameof().

EDIT: nameof() is evaluated in compile time, that's the main reason :)