ArticleDirectory
Ref: http://csharpindepth.com/Articles/General/BluffersGuide3.aspx
Obviusly C # In depth teaches the new features of C #3In depth. However, if you want to bluff it for the moment (just until your copy of the book arrives, of course)-welcome to the bluffer's guide. this isn't intended to give you enough information to be useful when coding-but you can pretend you know what you're talking about in suitably geeky company. more seriously, it will give youVeryRough overview to give some context if you choose to investigate a particle feature further. (See also: bluffer's Guide to C #2 .)
Each of the major features of C #3 is here,:
- A brief description of the feature, usually with an example
- A couple of "extra bluff power" phrases to throw into conversation to get bonus points from your listeners-so long as they don't quiz you further
- A couple of "call their bluff" claims which sound plausible, but are actually inaccurate. If you feel someone else is perhaps overstating their experience, see if they spot these traps.
Automatic propertiesdescription
Automatic properties are a simple way to write properties which just get and set their values directly from/to a backing variable. For example, this Code:
String name;
Public string name
{
Get {return name ;}
Set {name = value ;}
}
Can be written in C #3 like this:
Public string name {Get; set ;}
You can specify separate access levels for the getter and the setter, just like in C #2.
Extra bluff power
- The compiler-generated backing variable always contains angle brackets (<>) So the variable can never legitimately be referenced in C # code, and it will never clash with a hand-written variable.
- If you use automatic properties in
Struct
, You need to include an explicit call to the parameterless constructor from each additional constructor you write.
Call their bluff (untrue statements)
- Automatic properties are officially called "auto-properties" in the specification. (reality: They're called automaticallyImplementedProperties .)
- Automatic properties are indistinguishable from normally manually generated properties. (reality: the compiler adds
Compilergenerated
Attribute to both the getter and the setter .)
Object and collection initializersdescription
Object initializers allow you to set the properties of an object very simply at construction time. Collection initializers are similar, allowing you to populate a collection. Examples:
// Object initializer
Processstartinfo psi = new processstartinfo
{
Filename = "notepad.exe ",
Arguments = "C: \ autoexec. Bat ",
Useshellexecute = true
};
// Collection initializer for list
List <string> words = new list <string>
{"The", "quick", "brown", "Fox", "jumped", "over", "the", "lazy", "dog "};
// Collection initializer for dictionary
Dictionary <string, int> ages = new dictionary <string, int>
{
{"Jon", 31 },
{"Holly", 32 },
{"Tom", 4}
};
Extra bluff power
- You can nest object and collection initializers, creating whole trees of objects.
- Collection initializers require
Ienumerable
To be implemented, but the compiler never actually uses anything from the interface.
Call their bluff (untrue statements)
- Object initializers only work with properties. (reality: Object initializers can set fields as well, but only if they're accessible .)
- The
Dictionary
Type has special support maid for collection. (reality: the compiler just tries to find an appropriate overloadAdd
.)
Implicitly typed local variables and arraysdescription
Local variables declaredVaR
Are treated as if they were declared with the type of the expression used to initialize the variable. arrays can be initialized without specifying the type, and the type is inferred from the elements of the initializer. examples:
// Name is of type system. String
VaR name = "Jon ";
// Initializer can use properties, methods etc
VaR time = datetime. now;
// Array type is inferred to be system. String
String [] words = new [] {"hello", "there "};
Extra bluff power
- You can't use implicit typing (without casting) if the initializer is the null literal
- The type of an implicitly typed array must be the same as one of the elements of the array-you can't do
New [] {"hello", new memorystream ()}
And keep CT the compiler to an infer an element typeSystem. Object
.
Call their bluff (untrue statements)
VaR
Is short for "variant". (reality: the specification doesn't say whatVaR
Is short for, but it's almost certainly "variable". Variants such as those in com etc behave very differently, with execution time typing. The variable is still statically typedVaR
.
- You can declare the return type of a method to be
VaR
. (Reality: This isn't the case in C #3. It's possible it cocould become a feature in a future version, using inference over all the typesReturn
Statements .)
Anonymous typesdescription
Anonymous types persuade the compiler to create types with appropriate constructors and read-only properties, and then create instances of the type. these are primarily used within Query expressions, but can be used elsewhere. example:
VaR person = new {name = "Jon", age = 31 };
String name = person. Name;
Int age = person. Age;
Extra bluff power
- The generated type (with the ms c #3 compiler) is actually generic, and may be used for different types which have the same property names and order (but different property types ).
Equals
AndGethashcode
Are overridden to cater for simple cases of memberwise equality.
Call their bluff (untrue statements)
- You can't use
VaR
With anonymous types. (reality: a large part of the reason for the existenceVaR
Is to support anonymous types. Otherwise you cocould never declare a variable which used an anonymous type !)
- Anonymous types are always generated with a name beginning
??
. (Reality: the Microsoft C #3 compiler always makes anonymous type names start<>
. Starting??
Wocould have been just as valid tive at preventing it from being a valid C # identifier, admittedly, but it's not what happens in the current implementation .)
Lambda expressionsdescription
Lambda expressions (expressions containing=>
In) are similar to anonymous methods in C #2. They allow closures to be expressed simply, and can be converted into delegates or expression trees (see next point). For example,List <t>
ContainsConvertall
Method Taking a delegate. to convertList <int>
IntoList <double>
, Where each value in the resulting list is half the corresponding value in the original list, we cocould write:
List <int> original = new list <int> {0, 1, 2, 3, 4, 5 };
List <double> halved = original. convertall (x => X/2.0 );
Extra bluff power
- There are several "optional" parts to lambda expressions-for example you can optionally put code in braces, and have multiple statements instead of just a single expression.
- Although lambda expressions are supported in vb9, the statement body form described in the previous point isn' t supported.
Call their bluff (untrue statements)
- Anders hejlsberg coined the term "Lambda expression" in reference to his student fraternity house. (reality: lambda expressions have been around for a long time, as part of lambda calculus .)
- Lambda expressions completely replace anonymous methods in C #3. there are no good reasons ever to use an anonymous method any more. (There's one feature of anonymous methods that isn't shared by lambda expressions. if you don't specify a parameter list at all for an anonymous method, the expression can be converted into an instance of any delegate type which doesn't return a value or have any
Out
Parameters. This is handy for creating Event Handlers which don't care about their parameters at all .)
Expression treesdescription
Expression trees are a way of expressing logic so that other code can interrogate it. when a Lambda expression is converted into an Expression Tree, the compiler doesn't emit the IL for the lambda expression; it il which will build an expression tree representing the same logic. this is how LINQ providers such as LINQ to SQL work-it converts expression trees into SQL, interval tively.
Extra bluff power
- There are restrictions on what lambda expressions can be converted into expression trees-they have to be single expressions rather than having statement bodies, for instance.
- You can build up expression trees "manually" using the classes in
System. LINQ. Expressions
Namespace.
Call their bluff (untrue statements)
- Expression trees can only do very simple things-they can't call methods etc. (reality: expression trees are very flexible, and can call properties, methods and constructors, use operators, etc .)
- Expression trees only ever represent delegates. (reality: expression trees built up from lambda expressions always have a delegate type with the same signature, but you can build up expression trees completely separately, without referring to delegates at all .)
Extension methodsdescription
Extension methods are a piece of syntactic sugar to make it look like you're calling an instance method on a value when actually you're re calling a static method, passing that value as the first parameter. they're really important when it comes to query expression translation, and are useful in other ways too. example:
Public static class extensions
{
Public static string reverse (this string X)
{
Char [] C = x. tochararray ();
Array. Reverse (C );
Return new string (C );
}
}
...
String greeting = "Hello World ";
String backwards = greeting. Reverse ();
Console. writeline (backwards); // prints "dlrow olleh"
Extra bluff power
- Extension methods can only be declared in a static, top-level class.
- Although the compiler uses
System. runtime. compilerservices. extensionattribute
To find and indiciate extension methods, you can still use them in. NET 2.0 if you define your ownExtensionattribute
In the right namespace.
Call their bluff (untrue statements)
- Extension methods can only be applied to reference types. (reality: extension methods can be applied to any type, even primitives such
Int
. I 've defined some handy extension methods to allow expressions such19. June (1976) + 8. Hours ()
.)
- Extension methods can't be generic. (reality: Most of the extensions methods you're likely to come into SS in the framework-I. e. LINQ-are generic .)
Query expressionsdescription
Query expressions are a type of syntax somewhat unlike the rest of C #. it is transformed into non-expression-query C # And then normal compilation is applied. for instance, a query expression:
VaR query = from word in words
Where word. length> 4
Select word. toupper ();
Is translated:
VaR query = words. Where (WORD => word. length> 4)
. Select (WORD => word. toupper ());
The above wowould then typically use extension methods to implement the valid tive query.
Extra bluff power
- Query expressions are also knownQuery comprehensionsAlthough the word "Comprehension" doesn't appear a single time in the C #3 specification.
- It's the magic of lambda expressions being converted into either delegate instances or expression trees that allows Query expressions to work against databases, XML, local collections etc, all relatively seamlessly.
Call their bluff (untrue statements)
- the translation behaviour of Query expressions into code without Query expressions is compiler-dependent. (reality: It's very precisely specified, so Query expressions shocould work the same way with different compilers, such as
MCS
(the mono C # compiler ).
- Query expressions only work against
ienumerable
and derived types such as iqueryable
. the translation process has no idea what the rest of the compilation process will do with the translated result. it may result in extension methods being called, it may result in instance methods being called. there May be sequences such as ienumerable
, or a different LINQ provider may work with a completely separate set of types.