Prohibited variable names - c#

Is it somehow possible to call a C# variable return?
I need to deserialize JSON data and there is a field called return.
And I am unable to create class with this name to create object for deserialization :-/
Thank you.

Either use #return or simply annotate it (JSON.NET):
[JsonProperty(PropertyName = "return")]
public string MyPropertyName {get; set;}

You can use keywords as identifiers by prefixing them with #:
public int Foo()
{
int #return = 5;
return #return;
}
Note that this is not necessary for the so-called contextual keywords, such as LINQ operators, var and others that came later. Those have special rules where they can appear which allow them to be used as identifiers.

Try prefixing the variable name with '#'.
http://msdn.microsoft.com/en-us/library/aa664670%28v=vs.71%29.aspx

Related

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.
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.
So I ran into a similar issue and found two workable solutions:
If you want to have the namespaces as well just include them in the expression sent to either full name implementation
First:
public ref struct FullNameOf<T>
{
string _fullName;
public FullNameOf(T _, [CallerArgumentExpression("_")] string fullName = "" )
{
_fullName = fullName;
}
public static implicit operator string(FullNameOf<T> obj)
=> obj._fullName;
}
Second:
public static class FullName
{
public static string Of<T>( T _, [CallerArgumentExpression( "_" )] string fullName = "" )
=> fullName;
}
The usage would look something like this:
public class This
{
public class Is
{
public class A
{
public class Very
{
public class Nested
{
public class Property
{
public static string Here = string.Empty;
}
}
}
}
}
}
Console.WriteLine( $"nameof: {nameof(This.Is.A.Very.Nested.Property.Here) }" );
Console.WriteLine( $"fullnameof: { new FullNameOf<string>(This.Is.A.Very.Nested.Property.Here) }" );
Console.WriteLine( $"fullnameof func: {FullName.Of( This.Is.A.Very.Nested.Property.Here )}" );
The output is:
nameof: Here
fullnameof: This.Is.A.Very.Nested.Property.Here
fullnameof func: This.Is.A.Very.Nested.Property.Here
Another options is to make it into a static function like:
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.
Inspired by #Ignaz503's answer I came up with an extension method that works in C# 10 or later, and which will give the full name of a type whose name is passed in using the nameof() operator with a fully-qualified name:
public static class FullName {
public static string Of(string _, [System.Runtime.CompilerServices.CallerArgumentExpression("_")] string fullTypeName = "") {
if (fullTypeName.StartsWith("nameof(") && fullTypeName.EndsWith(")")) {
return fullTypeName[7..^1];
}
return fullTypeName;
}
}
Example usage:
Console.WriteLine("Full name: " + FullName.Of(nameof(MyApp.Web.Extensions.MyExtensionClass)));

Adding suffix to XmlElement C# parser

I'm dealing with a XML file which has support for different languages, I want to parse this XML into C# classes using XDocument/XElement (using System.Xml.Serialization). The XML is slightly complex but what I want to achieve should be simple, yet I can't figure it out.
Basix XML example:
<root>
<word_EN>Hello</word_EN>
<word_DE>Hallo</word_DE>
<word_FR>Bonjour</word_FR>
<root>
How I want my parser to look like:
[XmlRoot("root")]
public class Root
{
[XmlElement("word_" + LanguageSetting.SUFFIX)]
public string word { get; set; }
}
I want to get the suffix from another class and I want to be able to change it. I can set the suffix as a const string but then I can't change it. Using a global variable also does not work.
static class LanguageSetting
{
private static string _suffix = "EN";
public static string SUFFIX
{
get { return _suffix; }
set { _suffix = value; }
}
}
Error:
An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
What is the proper way of adding the suffix?
The correct way of doing this would be for your language suffix to be an XML attribute on the word element but this may not be possible for you.
You are receiving this error because a compile time constant must be use in attribute decorations. LanguageSetting.Suffix is static, but not a constant. Try using the const keyword instead.
In XML, different tag names represent different object types. The best solution for your current XML document is you have seperate classes for each supported language, all inherited from a common class (eg. WordBase).

C#: How to add a class member named "protected"

I'm fairly new to C# but have extensive experience in Objective-C and OOP. I'm using Json.NET to automatically parse API responses to objects. It so happens that one of the objects returned has a property named protected. Obviously this is a problem, because protected is a keyword for class member declaration.
"protected": true
Is it possible to add a member with the name protected at all?
Is it possible to add setters and getters that get triggered, if the parser tries to set the protected property? (but assign the value to a private member named _protected)
Should I modify the parser to behave different when he encounters a property named protected?
Thanks for any advice.
1:
For question #1: You can put an # symbol before it any keyword you want to use as a variable name.
E.g.
public string #protected {get; set; }
I recommend against doing this, however. You should be able to remap the "protected" field in your JSON to a different property in your POCO.
2:
private string _protected;
public string #protected
{
get
{
//any additional code you want
return _protected;
}
set
{
//any additional code you want
_protected = value;
}
}
3:
Up to you!
I implemented this solution:
[JsonProperty("protected")] public bool Protected { get; set; }
Like Daniel Mann suggested in his comment:

How to define named Parameters C#

This seems like a simple question, but for some reason I can't find the answer anywhere. Basically, I'd like to be able to implement a constructor that takes NamedParameters.
By named parameters, I do not mean parameters with default values (optional parameters) such as:
public SomeMethod(){
string newBar = Foo(bar2 : "customBar2");
}
public string Foo(string bar1 = "bar1", bar2 = "bar2" ){
//...
}
A good example of what I'm trying to achieve is the AuthorizeAttribute from the System.Web.Mvc assembly. Which you can use the following way:
[Authorize(Roles = "Administrators", Users = "ThatCoolGuy")]
public ActionResult Admin(){
}
The constructor's signature in intellisense looks like the following example and I believe (please confirm) that those NamedParameters are mapping to class properties.
AuthorizeAttribute.AuthorizeAttribute(NamedParameters...)
Initiliaze new instance of the System.Web.Mvc.AuthorizeAttribute class
Named parameters:
Order int
Users string
Roles string
Please note:
The syntax of defining the parameter name when calling a method has nothing to do with optional parameters:
You can use Foo(bar1 : "customBar1"); even if Foo is declared like this: void Foo(string bar1)
To answer the question:
My guess is that this is syntactic sugar similar to the object initializers introduced in Visual Studio 2010 and therefore you can't use this for your own classes.
The behaviour you are talking about is specific for attributes and cannot be reused in "normal" classes constructors.
You don't need to "implement" anything.
The parameters can be used in the manner you describe just by existing as parameters on the constructor.
You do need to be using C# 3.5 or above, when they were introduced.
Your example will compile and run on C# 4.0 / Visual Studio 2010 without modification.
See Named and Optional Arguments (C# Programming Guide) on MSDN.
In regards to properties on the object, that do not have a corresponding constructor arguments, the exact syntax is specific to attributes and can't be replicated, though, with object initializers you can get close.
You can use the builder/constructor info pattern together with property initializers.
class PersonInfo
{
public string Name { get; set; }
public int? Age { get; set; }
public Color? FavoriteColor { get; set; }
public Person BuildPerson()
{
return new Person(this);
}
}
class Person
{
public Person(PersonInfo info)
{
// use info and handle optional/nullable parameters to initialize person
}
...
}
var p = new Person(new PersonInfo { Name = "Peter", Age = 15 });
// yet better
var p = new PersonInfo { Name = "Peter", Age = 15 }.BuildPerson();
I however don't understand, why you don't just use named parameters and provide null for indicating optional parameters.
class Person
{
public Person(string name = null, int? age = null, Color? favoriteColor = null) { /* ... */ }
}
var p = new Person(name: "Peter", age: 15);
Named parameters are NOT specific to attributes. It's a language syntax that can be used everywhere. It's fine to use properties for initialisers but you don't always want to have internals set as set properties.
Just instantiate you class using:
TheClass c = new Theclass(param3:firstValue, param1:secondValue, param2:secondValue);
With regards to this part of the question:
"I however don't understand, why you don't just use named parameters and provide null for indicating optional parameters."
The reason named parameters are nice is you don't need to provide extraneous values in parentheses, just what you want to specify, because if it's optional you shouldn't even need to put null. Furthermore, if you specify null, you are overriding any default value for that parameter which makes it optional. Being optional implies there's a default value meaning nothing passed in.
Property initialisation at instance time is purely there for convenience. Since C there has been the ability to initialise values at construction time on types. Which is handy if those values can't be specified in the constructor. I personally feel that the convenience of them has spoiled people and it get a little too liberal and make everything public get AND set. Just depends on the design and security of properties you need.
I doubt that's possible. This is something specific for attributes.
I think the closest option is to use an object initializer:
class Foo {
public string Name {get;set;}
public int Data {get;set;}
}
var foo = new Foo {Name = "MyName", Data = 12};
try to use this signature
[AttributeUsage(AttributeTargets.Class)]
before the name of your class
Please refer to MSDN specification for full description:
https://msdn.microsoft.com/en-us/library/aa664614(v=vs.71).aspx
"Each non-static public read-write field and property for an attribute class defines a named parameter for the attribute class".
Visual C# 2010 introduces named and optional arguments. Named argument able you to specify an argument for a particular parameter by associating the argument with the parameter's name rather than with the parameter's position in the parameter list.Named arguments free you from the need to remember or to look up the order of parameters in the parameter lists of called methods.
static void Main(string[] args)
{
mapingFunction(snum2: "www.stackoverflow.com", num1: 1);
}
public static void mapingFunction(int num1, string snum2)
{
Console.WriteLine(num1 + " and " + snum2);
}
here you can see that argument are passed with our their order
What you probably want to do is implement public properties in your attribute:
public class AuditFilterAttribute : ActionFilterAttribute
{
public string Message { get; set; }
public AuditFilterAttribute() { }
}
They can be accessed through Named Parameters where you apply it:
[AuditFilter(Message = "Deleting user")]
public ActionResult DeleteUser(int userId)
Hope that helps...

Why can a class not have a static or constant property and an instance property of the same name?

I've never really questioned this before until now. I've got an input model with a number of fields, I wanted to present the string names of the properties through the input model so that my Grid can use them:
public class SomeGridRow
{
public string Code { get;set; }
public string Description { get;set; }
public const string Code = "Code";
}
Obviously, this gives the error:
The type 'SomeGridRow' already
contains a definition for 'Code'
Why can the CLR not cope with two properties of the same name which are, in my eyes, separate?
string code = gridRow.Code; // Actual member from instantiated class
string codeField = SomeGridRow.Code; // Static/Const
I'm now just using a child class called Fields within my inputs now, so I can use SomeGridRow.Fields.Code. It's a bit messy, but it works.
Because you can also access static (or, non-instance in this case) properties in the same way (inside the same class), and it would be a bit confusing, for example:
public class SomeGridRow
{
public string Code { get;set; }
public const string Code = "Code";
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
Because both this:
public class SomeGridRow
{
public string Code { get;set; }
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
And this:
public class SomeGridRow
{
public const string Code = "Code";
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
are valid ways to access properties, static or not. It doesn't answer the "why can't I?" question, but more of the why it's not allowed...it would be far too ambiguous IMO.
It probably could, but the designers of C# wanted to avoid ambiguities that can come from such use (abuse?) of language features.
Such code would end up being confusing and ambiguous to users (did I want the instance or the static method call?, Which one is right?).
In addition to the points already made about ambiguity, i would say that the naming needs to be relooked in such a case.
If two variables / fields having the exact same name in the same context i.e class but different values to me sounds more like a naming issue.
If they are exactly same, you dont need 2 fields.
If they are slightly different, you should have more accurate names.
In some other languages with a similar syntax, one can access a static member through an instance. So you could access both string.Empty and "abc".Empty.
C# doesn't allow this (though it does sort of from inside the class or a derived class, in that you can omit the class name for a static member and can omit this for an instance member), primarily to avoid confusion (I find it more handy than confusion tbh, but that's just me, I like switch fall-through too so what do I know).
Having introduced a stricter rule to allow for less ambiguity, it would be counterproductive to allow a new looser rule on the back of it that allowed for more. Think how many "why must I use this with property X but not property Y?" questions SO would have if it was allowed (we'd have to force this with property X to be clear we meant the instance member).

Categories