Introduce DataBase,Asp.net,JavaScript,Xml,Html,Css,Sql,Php,ASP.NET Controls,AJAX,Tools,HTML,CSS,JavaScript,Open Source Project,WPF,.Net Framework,Linq
Top Recommended Hosting

C#3.0: Local Type Inference

by the3factory 2/28/2008 10:52:00 PM

Type inference is a wonderful feature for any language. It preserves type safety while allowing you to write more “relaxed” code. In other words, you can define variables and use them without worrying too much about their types, leaving it to the compiler to determine the correct type of a variable by inferring it from the expression assigned to the variable itself.

The price for using type inference might be less explicit code against the types you want to use, but in our opinion, this feature simplifies code maintenance of local variables where explicit type declaration is not particularly meaningful.

C# 3.0 offers type inference that allows you to define a variable by using the var keyword instead of a specific type. This might seem to be equivalent to defining a variable of type object, but it is not. The following code shows you that an object type requires the boxing of a value type (see b declaration), and in any case it requires a cast operation when you want to operate with the specific type (see d assignment):

var a = 2;       // a is declared as int
object b = 2;    // Boxing an int into an object
int c = a;       // No cast, no unboxing
int d = (int) b; // Cast is required, an unboxing is done

When var is used, the compiler infers the type from the expression used to initialize the variable. The compiled IL code contains only the inferred type. In other words, consider this code:

int a = 5;
var b = a;

It is perfectly equivalent to this example:

int a = 5;
int b = a;

Why is this important? The var keyword calls to mind the Component Object Model (COM) type VARIANT, which was used pervasively in Visual Basic 6.0, but in reality it is absolutely different because it is a type-safe declaration. In fact, it infers the type just as you wrote it.

To some, var might seem to be a tool for the lazy programmer. Nevertheless, var is the only way to define an anonymous type variable, as we will describe later.

Note 

Variants were a way in COM to implement late binding with the type of a variable. There was no compile check using variants, and this caused a lot of nasty bugs that were revealed only when code was executed (most of the time, only when it was executed by end users).

The var keyword can be used only within a local scope. In other words, a local variable can be defined in this way, but not a member or a parameter. The following code shows some examples of valid uses of var: x, y, and r are double types; d and w are decimal; s and p are string; and l is an int. Please note that the constant 2.3 defines the type inferred by three variables, and the default keyword is a “typed” null that infers the correct type to p.

public void ValidUse( decimal d ) { var x = 2.3; // double var y = x; // double var r = x / y; // double var s = "sample"; // string var l = s.Length; // int var w = d; // decimal var p = default(string); // string }

The next sample shows some cases in which the var keyword is not allowed:

class VarDemo { // invalid token 'var' in class, struct or interface member declaration var k =0; // type expected in parameter list public void InvalidUseParameter( var x ){} // type expected in result type declaration public var InvalidUseResult() { return 2; } public void InvalidUseLocal() { var x; // Syntax error, '=' expected var y = null; // Cannot infer local variable type from 'null' } // }

The k type can be inferred by the constant initializer, but var is not allowed on type members. The result type of InvalidUseResult could be inferred by the internal return statement, but even this syntax is not allowed.

This simple language feature allows us to write code that virtually eliminates almost all local variable type declarations. Although this simplifies code writing, it can make reading code more difficult. For example, if you are going to call an overloaded method with versions of the method that differ in parameter types, it could be unclear which version of the method is being called by reading the code. Anyway, similar problems are generated from the poor use of method overloading: you should use different method names when the behavior (and the meaning) of the methods is different.

Related posts

Sign up for PayPal and start accepting credit card payments instantly.


Powered by BlogEngine.NET 1.2.0.0