4 ms·
I'm not sure of this direction. It looks like a rather large syntax explosion to cover a bunch of corner cases. C# doesn't want to become Perl. That's my initia
by bruceboughton 13y ago
I'm not sure of this direction. It looks like a rather large syntax explosion to cover a bunch of corner cases. C# doesn't want to become Perl. That's my initial gut feeling but perhaps that will change.
Does anyone know what the dollar syntax is? Similarly, the new dictionary initialiser syntax? Fisnlly, what is private protected?
Edit: these are from https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Documentation https://roslyn.codeplex.com/wikipage?title=Language%20Featur...
- chrisoverzero 13y agoGiven C# Dictionary access as Dict["key"], the equivalent using dollar syntax is Dict.$key. C# Dictionary initialization is currently something like this: var d = new Dictionary<string, string> { { "key", "value" }, { "but this one", "has spaces" } } The new syntaxes appear to be these: var d = new Dictionary<string, string> { $key = "value", ["but this one"] = "has spaces" } (Also, with C# 6's new abilities around constructor type inference, the type parameters may now be superfluous. I'm not certain, though.) The access modifier "private protected" appears to mean "only derived types that are also in the same assembly."
- bruceboughton 13y agoGood explanation, thanks. I don't understand the advantage of the dollar syntax though. One character shorter, and makes it look more object-y, obscuring the perf difference.
- philh 13y ago(Two characters shorter.) At least in python, I would love to have syntax like that. (I would use :: instead of .$, but maybe :: is already used in C#.) Maybe it's just because I work with JSON a fair amount, but I frequently have an it-might-as-well-be-an-object that happens to be stored in a dict. And in theory, this means I need to do foo['bar']['baz'], which is hard to read and unpleasant to type. In practice, I often use a class which overloads attributes as being dict keys, so I can use foo.bar.baz, but this has its own problems. foo::bar::baz would be great.
- deleted 13y ago[deleted]
- thomasahle 13y agoI can see the use case for json, but hardly for anything else. What's wrong with just using a class here? Seems very similar to how it would work in java script.
- philh 13y agoAny time you have a dict with stringy keys that you know when writing the program. HTML attribute lists, database records, http request parameters, config files.
- mattmanser 13y agoIf you have a 'it might as well be an object' in C# it's trivial to change it to an object with anonymous types and then blam you've got all the advantages of statically typed objects. I, as the next programmer, would hate you if you started trying to use C# as a dynamic language by abusing dictionaries, you're losing all the advantages of C# while still suffering the disadvantages.
- philh 13y agoMy gut reaction is that I'm not sold. With HTTP requests for example, I want to say `if 'id' in params`, whereas `if hasattr(params, 'id')` feels unnatural. But I also know that I'm accessing `params['id']` at programming time, so it would be great to shorten that to `params::id`. (And this ignores converting to JSON. The library I use is designed to be passed dicts. You can teach it to accept arbitrary objects, but that's kind of a hack.)
- jameshart 13y agoWhat's the value of using symbols instead of string literals to reference dictionary keys? It replaces a 'magic string' with a 'magic variable name', which is worse than the normal solution for magic strings, which is to move them to a constant. If I have code in one place that says: dict["key"] = "value"; and code elsewhere that says: var value = dict["key"]; I can make that code better today by adding const string KEY = "key" and then using dict[KEY] in both places. I can change the key in one place, and if I misspell the constant name in either location then the compiler tells me I have a problem. With the new syntax, I can now write dict.$key = "value"; and var value = dict.$key; but if I go ahead and change one of these: dict.$newkey = "value"; I'm not going to get a compiler warning when I try to read $key (am I?). Unless there's some smart tooling support, where's the win here? Key symbols aren't becoming a new type - I don't get to write var key = $key; var big_key = ["key with spaces"]; (so far as I'm aware - though I actually quite like the idea of a datatype that represents this kind of non-manipulable string identifier) I guess the new .$ syntax combines with the null-propagating ?. operator, so you could have nested dictionaries and access them with: dict?.$subdict?.$subsubdict which looks... horrible. And suffers from the fact that there's no null-propagating equivalent index access operator, ?[], so I can only use this trick on keys that can be written as C# symbols. I really feel like I'm completely missing what the use cases are for this capability...
- Xdes 13y agoI'm thinking it is the first step to a data type like Ruby's symbols. For the case of spaces I could see the underscore (_) getting used. var bigKey = $key_with_spaces;
- jameshart 13y agoBut if they were adding symbol support, it would have to work for accessing actual members, not for just faking string indexed members as if they were members. Symbol support would let you do things like this: public double GreatestExtent { get { Symbol directionOfGreatestExtent = $X; if (this.Y > this.X) directionOfGreatestExtent = $Y; return this.#directionOfGreatestExtent; } } (I'm making up some sort of syntax on the spur of the moment here) Clearly this can be written easily enough without symbol support, but you could argue that the intent of the logic is clearer here than it is in some alternative approaches. But the thing is that the kind of symbol they've given us isn't a syntax where $foo is a literal which means 'a symbol which accesses the member foo on the target', but instead a syntax where $foo means 'a symbol which accesses the indexer on the target which takes a single string as an argument and passes the string "foo" to it' - just like ["foo"] does. If I have my co-ordinates stored in a dictionary, I don't need this symbol support to be able to write that kind of logic: public double GreatestExtent { get { string directionOfGreatestExtent = "X"; if (this["Y"] > this["X"]) directionOfGreatestExtent = "Y"; return this[directionOfGreatestExtent]; } } In fact, it isn't even possible to really make use of the new $key support in that scenario because, as I said, they're not providing any mechanism to store the $key value and reuse it; you're forced to mix string literals and these key symbols: public double GreatestExtent { get { string directionOfGreatestExtent = "X"; if (this.$Y > this.$X) directionOfGreatestExtent = "Y"; return this[directionOfGreatestExtent]; } } I don't see how being able to make that change to this code is a step forward...
- gambler 13y agoI feel the same way. Too many corner cases, not many I deal with very often. So far null propagation seems like the most useful feature for cleaning up cluttered code I'm used to dealing with. Auto-property initializers are nice, but the syntax looks a bit ugly and I don't see them making that big of a difference in readability. I would rather see something that tackles the ugly-but-necessary construct I see the most: lazy-loading getters. Generic memorization of methods and properties would be even more useful. And yet even more useful would be something that could be used for both memoization and transparent caching: [Cache(For = 1000 /*milliseconds*/)] public GetSomethingFromDB(){ ... } That would be tough to implement well, though. Unless they added Python-like attributes. Which would give us memoization, caching an a myriad other things.
- Yrlec 13y agoYou might find these two links interesting: http://stackoverflow.com/questions/3180685/how-can-i-make-method-signature-caching/3180764#3180764 http://stackoverflow.com/questions/3180685/how-can-i-make-me... https://bitbucket.org/Yrlec/funccache https://bitbucket.org/Yrlec/funccache The first one is an answer I wrote on SO and the other is a library I wrote a couple of years ago. Both are are different solutions to the caching problem you describe.
- bruceboughton 13y agoLazy<T> is quite useful for lazy-loading/memoization.
- lukasLansky 13y ago... and writing your own Lazy<T> with time- or otherwise-limited cache validity is not a problem, also.
- gambler 13y agoYes, but cleaner syntax for it would be nice. Right now it looks quite messy: private Lazy<string> _someVariable =new Lazy<string>(SomeClass.IOnlyWantToCallYouOnce); public string SomeVariable { get { return _someVariable.Value; } } Imagine the same things with a long lambda inside.
- pjmlp 13y agoI think it is a consequence that programming in the large is complex and we all like our little feature to reduce boilerplate, while allowing for higher abstractions. In languages that allow for full macros, many of those features can be implemented as library instead, which also creates the problem everyone has their own little DSL. Anyway looking to the history of computing, all mainstream languages that started simple as a movement against complexity of some sort, ended up becoming more complex release after release.