void Main()
{
Test t = new Test
{
A = "a",
B = "b", // <-- erroneous trailing comma
};
}
public class Test
{
public string A { get; set; }
public string B { get; set; }
}
I find the above typo in my code quite a lot. I'm always suprised that the compiler doesn't seem to care about this. Why is the above not a syntax errror? Is there any actually valid use for it?
I find the above typo in my code quite a lot. I'm always suprised that the compiler doesn't seem to care about this. Why is the above not a syntax errror?
Because the people designing the C# syntax grammar were smart enough to learn the lessons from other programming languages which didn't allow the dangling comma, to the constant irritation of programmers in those languages.
For example, ECMAScript (JavaScript) was silent on the issue initially, and so naturally some implementations (SpiderMonkey in Firefox, Opera's JavaScript, etc.) allowed them while others (Microsoft's JScript) didn't. And so this led to a spate of "why doesn't this work in IE" questions here and elsewhere. (Fortunately, ECMAScript 5 explicitly allows them, and IE8 finally supports them in object initializers -- IE8 still treats array initializers in a non-standard way, though to be fair the dangling comma for those was only clarified in ECMAScript 5, too.)
You find this in lots of other places in the C# grammar too, like enums and array initializers.
It's not an error because it's convenient. To add to the initializer, you only have to add in one line instead of adding a comma to one line and entering a whole new line.
This is actually fairly common in list/array initialization in other languages too (Python, Ruby, Haskell come to mind).
I think it's allowed to simplify automatic code generation.
In this case you can have some sort of your program create code like this
...
for( char c = 'A'; c < 'Z'; c++ )
{
AddToOutput( c + " = \"+c.ToLower()+"\"," );
}
...
And don't have to care about removing the last trailing comma.
Related
Program ends when user types "!"
I don't know how to continuously asking users for inputs in my loop.
Console.WriteLine("Type a lowercase letter.");
char letter = char.Parse(Console.ReadLine());
while(letter !='!')
{
if(char.IsLower(letter))
{
Console.WriteLine("OK. Type another lowercase letter");
}
else
{
Console.WriteLine("Error");
}
letter = char.Parse(Console.ReadLine());
break;
}
As #Steve suggested, remove the break. When you're in a loop, break statement will instantly bring you outside of that loop.
In your case, your while was looping only once.
Read more here : https://msdn.microsoft.com/en-us/library/adbctzc4.aspx
Console.WriteLine("Type a lowercase letter.");
char letter;
Char.TryParse(Console.ReadLine(), out letter);
while (letter != '!')
{
if (char.IsLower(letter))
{
Console.WriteLine("OK. Type another lowercase letter");
}
else
{
Console.WriteLine("Error");
}
Char.TryParse(Console.ReadLine(), out letter);
}
Changed the Parse to TryParse since you can handle the error yourself. Well, you can surround Parse With a Try...Catch but exception are slow.
Parse v. TryParse
Why is throwing exceptions so slow?
all credit should go to #Steve
It looks like you are trying to learn some basic C# techniques. So another example that does what you say - with a different paradigm:
static void Main(string[] args)
{
var printout = new string[] { "Type a lowercase letter.", "OK. Type another lowercase letter", "Error" };
Console.WriteLine(printout[0]);
var sequance = SequenceOf(() => (Console.ReadLine() + " ")[0])
.TakeWhile(x => x != '!');
foreach (var item in sequance)
{
Console.WriteLine(printout[char.IsLower(item) ? 1 : 2]);
}
}
public static IEnumerable<T> SequenceOf<T>(Func<T> generator)
{
while (true)
{
yield return generator();
}
}
Once you get comfortable with this paradigm - it makes for more readable code in my opinion, and the way to read it is:
spit out canned response
generate a sequence (of line reads)(first char)
take from that sequence while the char is not !.
for each item in sequence - spit out canned response (conditional)
Explanation for some of my choices
I use the printout var to store canned responses. In a bigger app you would rather use resources to do something similar. sometimes the canned responses will be formatted responses this paradigm is still useful in that case. read more about resource management in the msdn.
the SequenceOf util func I wrote. Note that in C# a functions that return IEnumerable can be implemented in one of two fashions - the simple return new IEnumerable - returning an IEnumerable object - is the WYSIWYG way of implementing that func. The other more interesting way will be the iterator pattern this lets you write pretty looking code that just executes when the created IEnumerable's MoveNext function is called - and it 'yields' back to your code once it was either able to create your next value or it reached the end of the sequence - very neat and very useful code pattern. (the compiler recognizes the yield keyword and re-formats your code in a class implementing the IEnumerable interface. this is done automagically your own method is then rewritten by the compiler as "return new AutoGeneratedIEnumerableClass()" and the debugging line info is kept so you can have a nice debug session later)
you will further notice that the SequenceOf util functions is generic - that is it can be used to create a sequence of char - or of anything else. you can learn about generics in c# here
further more SequenceOf accepts a Func delegate parameter. delegates are just method objects. they are special objects that can hold a reference to a single method, and then be called just as a method can be with the () notation. In earlier versions of C# and the .net FW it made a lot of sense to create your own delegate objects with the delegate keyword. but microsoft aims to please - and in the latest versions of the FW you have generic reusable delegate objects that are suitable for most of your real world needs. learn more about delegates here
TakeWhile is a part of LINQ there is not enough praise to say about LINQ. I use it when I can. It makes for very readable code.
notice in the Main function when I use the SequenceOf I don't pass simple functions (though i can) - instead I use c#'s shorthand to write functions - lambda expressions - these, though they are just syntactic sugar, enable you to write clearer code when passing simple functions (simple behavior) to other functions - by the way - when a function gets another function as a parameter - it is called a higher order function
last but not least there is the ternary if - many people frown upon the question mark notation - I like to use in where the term is small and visually pleasing.
Hope this gets you places you wanted to go.
Have fun.
public void Finalise()
ProcessFinalisation(true);
Doesn't compile, but the correct version:
public void Finalise()
{
ProcessFinalisation(true);
}
Compiles fine (of course).
If I am allowed if's without brackets when the following code has only one line:
if(true)
CallMethod();
Why is the same not allowed for methods with one following line? Is there a technical reason?
The obvious answer is the language spec; for reasoning... I guess mainly simplicity - it just wasn't worth the overhead of sanity-checking the spec and compiler for the tiny tiny number of single-statement methods. In particular, I can potentially see issues with generic constraints, etc (i.e. where T : IBlah, new() on the end of the signature).
Note that not using the braces can sometimes lead to ambiguities, and in some places is frowned upon. I'm a bit more pragmatic than that personally, but each to their own.
It might also be of interest that C# inside razor does not allow usage without explicit braces. At all (i.e. even for if etc).
Marc is basically right. To expand on his answer a bit: there are a number of places where C# requires a braced block of statements rather than allowing a "naked" statement. They are:
the body of a method, constructor, destructor, property accessor, event accessor or indexer accessor.
the block of a try, catch, finally, checked, unchecked or unsafe region.
the block of a statement lambda or anonymous method
the block of an if or loop statement if the block directly contains a local variable declaration. (That is, "while (x != 10) int y = 123;" is illegal; you've got to brace the declaration.)
In each of these cases it would be possible to come up with an unambiguous grammar (or heuristics to disambiguate an ambiguous grammar) for the feature where a single unbraced statement is legal. But what would the point be? In each of those situations you are expecting to see multiple statements; single statements are the rare, unlikely case. It seems like it is not realy worth it to make the grammar unambiguous for these very unlikely cases.
Since C# 6.0 you can declare:
void WriteToConsole(string word) => Console.WriteLine(word)
And then call it as usual:
public static void Main()
{
var word = "Hello World!";
WriteToConsole(word);
}
Short answer: C# is styled after C, and C mandates that functions be braced because of how C function declarations used to be.
Long version with history: Back in K&R C, functions were declared like this:
int function(arg1, arg2)
int arg1;
int arg2;
{ code }
Of course you couldn't have unbraced functions in that arrangement. ANSI C mandated the syntax we all know and love:
int function(int arg1, int arg2)
{ code }
but didn't allow unbraced functions, because they would cause havoc with older compilers that only knew K&R syntax [and support for K&R declarations was still required].
Time went on, and years later C# was designed around C [or C++, same difference in terms of syntax] and, since C didn't allow unbraced functions, neither did C#.
I have a class which has a group of integers, say
foo()
{
int a;
int b;
int c;
int d;
....
string s;
}
Now the question is for the best readbility, the init() function for foo(), should it look like
void init()
{
a=b=c=d=1; //for some reason they are init to 1;
s = "abc";
}
or
void init()
{
a=1;
b=1;
c=1;
d=1;
s = "abc";
}
?
The reason for a string in class is a hint of other groups of same types might present and of course, the class might grow as requirement changes
EDIT: before this question goes too far, the intention of this question was simple:
In Effective C++ item 12 (prefer initialization to assignment in constructors), Scott uses chain assignment instead of a=c; b=c; I am sure he knows when to use what, but I also remembered the books I read also recommended to use int a; int b; which in similar case of assignments. In my program I have a similar situation of a group of related individual build-in types needs to be initialized and I have found by making a chain assignment does makes it easier to read especially if the class have many other different types instance variables. It seems to contradict with books I read and my memory, hence the question.
I happen to prefer the chained version, but it's completely a matter of preference.
Please note, however, that
a = b = c = 0;
is equivalent to:
c = 0;
b = c;
a = b;
and not
a = 0;
b = 0;
c = 0;
(not that it should matter to you which assignment happens first)
My personal preference is a=b=c=d for the following reasons:
It is concise, saves lines
It conveys the concept that (a/b/c/d) are initialized to the same thing, that they are related
However, caveat:
Don't do that if a/b/c/d are not related (and just happens to be initialized to 1). You'll reduce the readability of your code. Example:
a=c=1; // Foo-function related
b=d=1; // Bar-function related
Chaining assignments like this reduces the flexibility for you in the future to assign different initial values to the variables -- because then you'll have to break them up again.
Nevertheless, my personal recommendation is to chain assignments on variables that are related on concept/usage. In actual practice, the need to change an assignment usually doesn't come up often so caveat #2 should not typically pose a problem.
Edit: My recommendation may go against published guidelines. See the comments.
I guess it is a matter of opinion which is most readable. (Clearly so ... otherwise you wouldn't be asking.)
However Oracle's "Code Conventions for the Java TM Programming Language" clearly says to use separate assignment statements:
10.4 Variable Assignments. "Avoid assigning several variables to the same value in a single statement. It is hard to read."
My opinion?
Follow your project's prescribed / agreed style rules, even if you don't like them1.
If your project doesn't (yet) have prescribed / agreed style rules:
Try to persuade the other members to adopt the most widely used applicable style rules.
If you can't persuade them / come to a consensus, then just do this informally for the major chunks of code that you write for the project1.
1 ... or get out.
void Main()
{
Test t = new Test
{
A = "a",
B = "b", // <-- erroneous trailing comma
};
}
public class Test
{
public string A { get; set; }
public string B { get; set; }
}
I find the above typo in my code quite a lot. I'm always suprised that the compiler doesn't seem to care about this. Why is the above not a syntax errror? Is there any actually valid use for it?
I find the above typo in my code quite a lot. I'm always suprised that the compiler doesn't seem to care about this. Why is the above not a syntax errror?
Because the people designing the C# syntax grammar were smart enough to learn the lessons from other programming languages which didn't allow the dangling comma, to the constant irritation of programmers in those languages.
For example, ECMAScript (JavaScript) was silent on the issue initially, and so naturally some implementations (SpiderMonkey in Firefox, Opera's JavaScript, etc.) allowed them while others (Microsoft's JScript) didn't. And so this led to a spate of "why doesn't this work in IE" questions here and elsewhere. (Fortunately, ECMAScript 5 explicitly allows them, and IE8 finally supports them in object initializers -- IE8 still treats array initializers in a non-standard way, though to be fair the dangling comma for those was only clarified in ECMAScript 5, too.)
You find this in lots of other places in the C# grammar too, like enums and array initializers.
It's not an error because it's convenient. To add to the initializer, you only have to add in one line instead of adding a comma to one line and entering a whole new line.
This is actually fairly common in list/array initialization in other languages too (Python, Ruby, Haskell come to mind).
I think it's allowed to simplify automatic code generation.
In this case you can have some sort of your program create code like this
...
for( char c = 'A'; c < 'Z'; c++ )
{
AddToOutput( c + " = \"+c.ToLower()+"\"," );
}
...
And don't have to care about removing the last trailing comma.
I'm looking for a function like
public bool IsAReservedWord(string TestWord)
I know I could roll my own by grabbing a reserve word list from MSDN. However I was hoping there was something built into either the language or .NET reflection that could be relied upon so I wouldn't have to revisit the function when I move to newer versions of C#/.NET.
The reason I'm looking for this is I'm looking for a safeguard in .tt file code generation.
CSharpCodeProvider cs = new CSharpCodeProvider();
var test = cs.IsValidIdentifier("new"); // returns false
var test2 = cs.IsValidIdentifier("new1"); // returns true
The Microsoft.CSharp.CSharpCodeGenerator has an IsKeyword(string) method that does exactly that. However, the class is internal, so you have to use reflection to access it and there's no guarantee it will be available in future versions of the .NET framework. Please note that IsKeyword doesn't take care of different versions of C#.
The public method System.CodeDom.Compiler.ICodeGenerator.IsValidIdentifier(string) rejects keywords as well. The drawback is this method does some other validations as well, so other non-keyword strings are also rejected.
Update: If you just need to produce a valid identifier rather than decide if a particular string is a keyword, you can use ICodeGenerator.CreateValidIdentifier(string). This method takes care of strings with two leading underscores as well by prefixing them with one more underscore. The same holds for keywords. Note that ICodeGenerator.CreateEscapedIdentifier(string) prefixes such strings with the # sign.
Identifiers startings with two leading underscores are reserved for the implementation (i.e. the C# compiler and associated code generators etc.), so avoiding such identifiers from your code is generally a good idea.
Update 2: The reason to prefer ICodeGenerator.CreateValidIdentifier over ICodeGenerator.CreateEscapedIdentifier is that __x and #__x are essentially the same identifier. The following won't compile:
int __x = 10;
int #__x = 20;
In case the compiler would generate and use a __x identifier, and the user would use #__x as a result to a call to CreateEscapedIdentifier, a compilation error would occur. When using CreateValidIdentifier this situation is prevented, because the custom identifier is turned into ___x (three underscores).
However I was hoping there was something built into either the language or .NET reflection that could be relied upon so I wouldn't have to revisit the function when I move to newer versions of C#/.NET.
Note that C# has never added a new reserved keyword since v1.0. Every new keyword has been an unreserved contextual keyword.
Though it is of course possible that we might add a new reserved keyword in the future, we have tried hard to avoid doing so.
For a list of all the reserved and contextual keywords up to C# 5, see
http://ericlippert.com/2009/05/11/reserved-and-contextual-keywords/
static System.CodeDom.Compiler.CodeDomProvider CSprovider =
Microsoft.CSharp.CSharpCodeProvider.CreateProvider("C#");
public static string QuoteName(string name)
{
return CSprovider.CreateEscapedIdentifier(name);
}
public static bool IsAReservedWord(string TestWord)
{
return QuoteName(TestWord) != TestWord;
}
Since the definition of CreateEscapedIdentifier is:
public string CreateEscapedIdentifier(string name)
{
if (!IsKeyword(name) && !IsPrefixTwoUnderscore(name))
{
return name;
}
return ("#" + name);
}
it will properly identify __ identifiers as reserved.