Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use nameof to get the fully qualified name of a property in a class in C# Attributes?

I am using Foolproof library in ASP.Net MVC project and in some cases I need to check a property within a member class of my model using attribues .

For example I have a user class which has a property of type Address and I need to check for the City in the Address.

The attributes need to have the name of the property in a dot notation for my example you could say "Address.City".

Of course this suffers from refactoring issues if I need to change either names later on (Address or City)

I need to use nameof for that purpose and of course if I use it like this :

nameof(Address.City) 

it will produce City Only.

I need nameof because it produces constant values that are allowed in attributes.

I found that the reference tells it is possible but not how. https://msdn.microsoft.com/en-us/library/dn986596.aspx in remarks section it says:

If you need to get the fully-qualified name, you can use the typeof expression along with nameof.

but I couldn't find any place to tell how to do this.

Can anyone help, please? Thanks in advance for your time and effort.

Update : October-2019

As I looked up the documentation again they removed the above statement and replaced it with.

As the preceding example shows, in the case of a type and a namespace, the produced name is usually not fully qualified.

like image 997
Ahmed Samy Moursi Hashwa Avatar asked Nov 29 '16 00:11

Ahmed Samy Moursi Hashwa


People also ask

What does Nameof return?

C# nameof operator returns the unqualified string name of a variable, type, or member.

What is fully qualified name in C#?

In C#, the full name of the class starts from its namespace name followed by dot(.) operator and the class name, which is termed as the fully qualified name of the class.

When was Nameof added to C#?

The nameof operator, added in C# 6.0, addresses this — it allows capturing the string names of symbols that are in the scope.


Video Answer


2 Answers

After a bit of digging I found that this issue has been discussed already upon developing this feature in here https://roslyn.codeplex.com/discussions/552376 and specially in here https://roslyn.codeplex.com/discussions/552377 for the comment by MgSam

As it is proposed, I can imagine something like this happening to get a fully qualified name: BindToFullyQualifiedName(nameof(Microsoft) + "." + nameof(Microsoft.Data) + "." + nameof(Microsoft.Data.Entities) + "." + nameof(Microsoft.Data.Entities.EntityObject));

The answer was

I think typeof(EntityObject).FullName is fully sufficient in your case.

Which concluded the discussion with no further comments on another way to do this.

Unfortunately this means there is no way to user nameof and get the fully qualified name directly for usage in Attributes.

Probably this is the end of it and I suppose Microsoft should change their documentation to make it more clear and precise.

like image 107
Ahmed Samy Moursi Hashwa Avatar answered Sep 21 '22 19:09

Ahmed Samy Moursi Hashwa


If you don't want to specify a "reference" type (not 'reference type' in the C# sense) to get your target namespace (why should you?), and to save putting a string of nameof operators separated by ., then you can include the "base" namespace by getting the assembly name if it follows the default convention and is named the same as your default namespace, as thus:

$"{Assembly.GetExecutingAssembly().GetName().Name}.{nameof(Level1Namespace)}.{nameof(Level2Namespace)}"

This will at least save you some code, and protect you against refactors where you change the assembly name or even move an entire hierarchy of classes to another assembly, but it of course won't protect against changes within the namespace hierarchy itself. To protect against that, then I think you will indeed need a "reference" type such as perhaps an abstract class or interface that all other classes in the desired namespace inherit, and then apply the accepted answer solution to it.

like image 31
Neo Avatar answered Sep 23 '22 19:09

Neo