Does StringBuilder implements IDisposable? No, it doesn't. And, what about SqlDataReader? Can you remember which classes implement a given interface? Is there any simple way to find it without interrupting your workflow to check the inline help? Then, why does using fails to compile when the instance type doesn't implement that interface?
In Freya, this is no longer a requirement. When the instance type in a using statement does not implement IDisposable, the compiler does not complain, but no finalization is generated for the statement:
using var sb := new StringBuilder do
Another new experimental feature is shown in the previous example: inline variable declaration, in true C# 3.0 fashion. Actually, this kind of simple type inference was already present in Freya. What's new is the presence of var to make clear we are introducing a (block scoped) local variable.
for var i := 0 to list.Count - 1 do
// See note below...
with var item := list[i] do
Without var, it would be hard to tell whether we are using an already declared control variable, or just asking for a new local control variable in statements like this:
// See note below...
for i := low to high do ...
Have you noticed the change in the with statement? We have sacrificed the old semantics of the traditional Pascalian with. Now, this statement is used to introduce new local variables and an associated scope for them, but there's no assumed prefix as in Pascal and Delphi.
Updated:The with statement has been dropped from Freya, since it could be substituted by our "extended" using statement. However, we had to make another change in the semantics of using: value type variables declared at the header are no longer read only. That's not a great deal, since IDisposable is almost always implemented by classes instead of records. Finally, Freya, as C#, requires a dedicated variable in for statement. You cannot "recycle" anymore an already existing local, as in Delphi.
And this is another example of type inference for local variables:
for var color in [Colors.White, Colors.Blue] do
if color in [Colors.Red, Colors.Blue] then
Brackets are used to construct arrays, and the in operator in the conditional statement translates as a call to ICollection<>.Contains, in the most general case. In this simple example, the compiler optimizes the check and inlines the expression.
Labels: declaration, locals