|
BobJanova wrote: But of course one of the places you can't use it is in field declarations which is where you want to do that a lot! Of course you can! Just do what the original poster had found being done to it.
|
|
|
|
|
Why 10 years? Var was introduced with C# 3.0, which was released about 6 years ago. I hope you weren't trying to use it before then.
|
|
|
|
|
Long ago, in a galaxy far far away, was something called Visual Basic.
|
|
|
|
|
You are thinking of the VB.NET variant type, which is not the same thing as C#'s implicitly typed "var". In C#, a var variable will have a compile-time type defined by the type on the right hand side of the assignment. In VB.NET, a variant type can change at runtime (unlike in C#).
However, VB.NET now has the ability to implicitly type variables, just as with C#'s var. However, I think in VB.NET, you just do that by leaving off the type (e.g., Dim x = 5 ).
Variants are an abomination. Implicitly typed variables are necessary (e.g., for anonymous types), and can be nice (e.g., for very long type declarations). You can read more about implicitly typed variables here. The closest thing to VB.NET's variant type in C# would be a variable of type "Object".
|
|
|
|
|
Ah, I see. Thanks for that. Agree, variants are awful; implicit typing? Doesn't sound too helpful for complex walkthrough's, although I love it in Python.
|
|
|
|
|
Not sure what you mean by "complex walkthroughs".
|
|
|
|
|
One job I had meant examining code by eye for the most part. Would have meant a lot of extra difficulty if the variables had not been explicitly declared.
It was a mixture of VC6 and C# interop. The VC6 couldn't be unit tested, it was a 500,000 LOC chunk that could be run through the VS6 debugger, but not split up.
Horrible code.
|
|
|
|
|
Simon O'Riordan from UK wrote: I haven't used var except where essential in almost 10 years. Wow, you must be really advanced. When I took C# training in 2005 var never came up and I read the manuals from cover to cover and never saw the command. I was under the impression it was introduced in 2005. (I can easily be totally wrong about that.)
When is it ever essential? There is always:
object x = ...
|
|
|
|
|
It was present in Visual Basic. Before .Net was a squirt in a squirts imagination.
|
|
|
|
|
Er, no it wasn't.
VB 6 had variant's but that's a different and altogether more abhorrent kettle of fish[^].
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
Alan Kay.
|
|
|
|
|
Yes. We sorted all that out last week. Do try and keep up 007.
|
|
|
|
|
Sorry for adding a late comment - couldn't let your "object x =" stand there. This is NOT the same as using var (because in C# var means "I don't want to type - compiler look it up", or "I have an anonymouse type the compiler will know it's name later - but I don't!". Where holding a value as it's base type (in C# object is the base type of all reference types) is a complete other story!
|
|
|
|
|
johannesnestler wrote: couldn't let your "object x =" stand In no way did I intend to imply it was equivalent. I did mean to imply they are equivalent in the sense of "I'm too lazy to look up or care what object I am dealing with." I have to admit I am too lazy to look it up now, but if you are passed an object field and set "var x = field". I know the true class isn't ever lost, but is x now the true object type?
|
|
|
|
|
The "var" thing in C# is often miss-interpreted. Because everyone thinks of runtime type identification (VB...). But in C# it's not - it's only syntactic sugar if you don't want to retype complicated Type-names like: Dictionary<mykeyclass<int>, List<list<double>>>, but the compiler always knows what type it is - it's normal strong compile-time type checking. Even the IntelliSense knows the type.
But there are situations it is neccessary: you - as the programmer - sometimes do not know which type an expression will give back (anonymouse types), but the compiler will create a class for the anonymouse type during compilation and can fill in the missing type instead of the var keywords - but again: AT COMPILE TIME.
So in your example: object field = new SomeClass(); var x = field; will result in x interpreted as object not SomeClass. Don't mix that up with GetType() or typeof operator in c# - you can always ask an object for it's type - AT RUNTIME.
This is an better example: object field1 = new SomeClass(); var field2 = new SomeClass(); Where for field1 you are holding a SomeClass-instance as a base class reference (everything derives from object) where field2 is totally equivalent to: SomeClass field2 = new SomeClass();
If you want my personal opinion: I just use it where needed (anonymouse types) or for LINQ (there you often have those ugly long typenames). For me it had another nice side-effect I didn't think of in the first place: If you have specific algorithms or snippets and used the var keyword instead of the real type, you get code that is great for copy-pasting arround. This sometimes helps to focus on the underlaying constructs - and it helped me "to see" how repetitive code can be unified.
var regards = from reg in AllRegards
where reg.Quality = "best"
select new { Regards=reg, Quality=reg.Quality };
(this would be valid C# (LINQ) giving back an anonymouse type - you can not know it's Name, so use of var keyword is mandatory...)
|
|
|
|
|
Seems about the same as doing this in C or C++:
/* What could possibly go wrong */
#define int double
Since the substitutions are done before the tokens are interpreted.
|
|
|
|
|
What's old is new. I found the following:
#define void int in some C code when I started my current job.
Software Zen: delete this;
|
|
|
|
|
Another two (three?) hours spent on this kind of typo:
public int LoadedSampleCount
{
get { return (int)GetValue(LoadedSampleCountProperty); }
set { SetValue(LoadedSampleCountProperty, value); }
}
public static readonly DependencyProperty LoadedSampleCountProperty =
DependencyProperty.Register("LoadedSampleCount", typeof(int), typeof(TreeWindowVM SampleSetLoaderVM), new PropertyMetadata(0));
This is a result of a "GUI refactoring" -- moving parts of code to an user control. And forgetting to set an owner of a dependency property to a new model view again. Awww...
Greetings - Jacek
|
|
|
|
|
Seems like some people like to make things in C# more complex than they need to be. Makes it much easier to generate bugs. They must have a great desire to become an entomologist.
One of the things that confused me was that people were changing readonly objects. Then the oh, duh, moment. the address and definition of the object can't change. Internal changes don't count as changing the object.
|
|
|
|
|
The owner of a dep roperty has to be changed to a new ViewModel, otherwise it wouldn't be visible in the XAML, in which a DataContext had been changed to that new ViewModel. Or I get it all wrong.
Greetings - Jacek
|
|
|
|
|
Sorry for late comment... but I have to ask: You think "readonly" should mean the same like "const"? Did you never had the need to "calculate" a later constant value? I like the "readonly" construct (keyword) and think it's a good thing to have. (and you can only reset in in constructors and not everywhere)
To the related topic you mentioned - that changing the through a readonly variable represented object doesn't count as changing the variable, and isn't forbidden -> it's completly clear for me that a pointer-variable change means to change it's content - the address it is representing not the object it is pointing to. That's also true for const pointers in C++ and all other languages I know - have you seen a language where a constant pointer means that the pointed object is immutable?
|
|
|
|
|
johannesnestler wrote: I have to ask: You think "readonly" should mean the same like "const"? Not really, I don't recall talking with the instructor about either const or readonly. And I didn't read anything in the books I'd bought for the training. I just recall seeing it for the first time on the job and my amazement that the values in the readonly object were being changed and the compiler wasn't complaining. Then an "Oh, duh" moment. You can't change the instance, but you can change the contents of the instance. This code is totally legal:
public class vals
{
public int age;
public DateTime date;
}
class x
{
public readonly vals val = new vals();
}
static void Main(string[] args)
{
x val = new x();
val.val.age = 20;
val.val.date = DateTime.Now;
... const has it's own peculiarities, basically it supports value types. When you read the documentation it says the only non-value type is string. I was taught that string was also a value type. I haven't read any documentation (other than const) that contradicts string is a value type. I got an eye opener several years ago when I read that you shouldn't send a string to unmanaged C++ code. Before that, I was totally confused by the statement that strings were IMMUTABLE. I can change the value of the string whenever I want! After I read that article I understood what was meant by that and it makes me believe that you can change a const string variable's value by passing it to that C++ code I mentioned. Much later I learned about Intern and IsInterned.
Because I am not dedicated to this language I don't consider myself near an expert in C#. More knowledgeable than some C# programmers, most dedicated C# developers know more than me.
|
|
|
|
|
I think the idea for the readonly keyword in C# was stolen from JAVA (final keyword). And solves the problem I mentioned. (What to do if a later constant value must be calculated?)
In the example you have given, you can see what I mean: What did you declare as readonly? The age or date properties? -> No, You declared the val variable of type vals as readonly.
Because vals is a reference type (you created it with the class keyword) the variable val is now holding the address of the new vals instance on the heap. - so val is a pointer. This is the variable that is immutable, you can not change this pointer (the address it is holding) in an other way but the rules for readonly keyword usage are dictating.
So if you don't know any language where a "constant pointer" means the object pointed to is immutable (nor do I), how would you expect it to behave in an imaginary language? What if the pointed object is holding a lot of other references (pointers). Should they be then immutable too? I think if you go that thought to the end, you will come to the conclusion that the current behaviour is the only logical consistent one - please correct me if I'm wrong...
greetings from Austria
|
|
|
|
|
The only thing wrong with the way readonly works is my initial impression of it when I first encountered it. I got that impression before I read any documentation on the property. First impressions can be exactly right, but they are usually wrong. As soon as I got it through my head that the object I was looking at was a reference type it came clear how readonly worked. Doesn't even have to be a reference type, everything has a reference location in memory, that's how const can work as well.
|
|
|
|
|
Just came across the following in some code I maintain:
foreach (Object item in group)
{
int i = 1;
string key = "SomeString_" + i.ToString();
}
I suspect the idea was to use i to help make the dictionary keys unique.
|
|
|
|
|
try
{
account.Save();
}
catch { ; }
|
|
|
|