Beruflich Dokumente
Kultur Dokumente
Did you know that you can use params to allow x = something[a, b, c, d] ?
Here's an example:
public IEnumerable<string> this[params string[] keys] {
get { return keys.Select(key => internalDictionary[key]).AsEnumerable(); }
}
The interesting thing is that you can have both indexers in the same class side-by-side. If someone
passes an array or multiple args they get an IEnumerable back. However, make a call with a single arg
and they will get a single value back.
2. Strings defined multiple times in your code are folded into one
instance
It's commonly believed that the following line of code will create a coup of strings every time, however
it will not.
if (x == "" || x == "y")
C#, like many other languages, employs string interning. This means that every string your program
compiles with gets put into an in-memory list that is referenced at runtime.
You can use String.Intern to see if its currently in this list but bear in mind that doing
String.Intern(what) == what will always return true as you just defined another string in your
source. String.IsInterned(wh + at) == what will also return true thanks to compiler optimizations.
String.IsInterned(new string(new char[] { w,h,a,t }) == new string(new char[] { w,h,a,t })
will only return true if you have what elsewhere in your program or something else at runtime has
added it to the intern pool.
If you have classes that build up or retrieve regularly used strings at runtime consider using
String.Intern to add them to the pool. Bear in mind once in they are in the pool they stay there until the
program exists so use String.Intern carefully. The syntax is String.Intern(someClass.ToString())
Another caveat is that performing (object)Hi == (object)Hi will return true thanks to interning. Try
it in your debug intermediate window and it will be false since the debugger does not intern your
strings.
You would think you wouldn't be able to modify internal strings, but that's not the case. Here's how:
((List<string>)x.AllStrings).Add("Hello");
Even AsEnumerable wont help as that is a LINQ method that does nothing. You can use AsReadOnly
which creates a wrapper around the list that throws an exception when you try to set anything. This is a
good pattern to use when doing similar things with your own classes if you need to expose a subset of
internal structures.
Its almost useful as now the second copy-and-pasted code block doesnt compile but a much better
solution is to split your method into smaller ones using the extract method refactoring.
This will print the value 5. Reorder the a and b declarations and it will output 0.
Its easy to think of private as meaning only this instance of a class can access them, but the reality is
that it means only this class can access it, including other instances of this class. This can be quite
useful for some comparison methods.