LINQ Route 2:c# 3.0 language features (top)

Source: Internet
Author: User

In the previous LINQ introduction, we have seen implicit type Var, extension methods (extension method), and lambda expressions. Yes, they are the cornerstone of LINQ technology, they make LINQ implementations possible, and simplify the writing of LINQ expressions. In this article, I will explore c#3.0 's efforts in language functions, including: implicitly typed local variables, automatic attributes, and anonymous types.

implicitly-typed local variables

C # is a strongly typed language, meaning that we must specify the exact type of the variable when declaring it, such as:

        Static void Declareexplicitvars ()

int 0
BOOL true
string " Hello, world!. "
}

Now C # 3.0 gives us a new keyword VAR, which you can use instead of a formal data type name (such as int, bool, string). When using the var keyword, the compiler infers the data type of the variable based on the initial value used to initialize the local variable. For example, the above variable declaration can be changed to the following code:

        Static   void Declareimplicitvars ()
{
// implicitly-typed local variables are declared: var varName = DefaultValue;
var 0;
var true;
var " Hello, world!. ";
}

The above two methods are equivalent, and the compiler can infer from the initial value that the type of type System.int32,mybool of the Myint type is System.String. system.boolean,mystring.

In addition, we can use implicit types for all types in the base class library, including arrays, generics, and custom types.

         Public   Static voidDeclareimplicitvars ()
{
//Declare implicit variables
varNumbers =New int[] {2,4,6,8};
varPersons =NewList<person> ();
varCar =NewSportscar ();

//Verify the data type using reflection
Console.WriteLine ("numbers is a: {0}", numbers. GetType (). Name);
Console.WriteLine ("persons is a: {0}", persons. GetType (). Name);
Console.WriteLine ("car is a: {0}", car. GetType (). Name);
}

The output results are as follows:

var in the foreach use in a statement

In the Foreach Loop statement, we can also use implicit types. As you would expect, the compiler infers the correct data type:

        Static   void Varinforeachloop ()
{
var New int [] 2468 };
foreach (varin numbers)
{
Console.WriteLine ("Item Value: {0}", item);
}
}
limitations of implicit type variables

It is important to note that there are several limitations when using the var keyword. First, an implicit type can only be declared with a method or a local variable within a property, and cannot use Var to define the return value, the type of the parameter, or the data member of the type.

Second, local variables declared with VAR must be assigned an initial value, and cannot be null as the initial value. The reason for this is that the compiler must be able to infer the actual type of the variable based on the initial value.

implicit type data is strongly-typed data

Implicitly typed local variables eventually produce strongly typed data. Therefore, the VAR keyword is not the same as the variant data type of a scripting language (such as VBScript or Perl), and for the latter, a variable can hold different types of values in its life cycle.

In fact, type inference preserves the strongly typed nature of the C # language and only affects the declaration of variables at compile time. After initialization, the compiler has inferred the exact data type for the implicit type variable. Assigning different types of values to a variable causes a compile-time error:

        Static   voidImplicittypingstrongtyping ()
{
//The compiler knows that s is the System.String type
vars ="This variable can only hold string data!";
s ="It ' s OK.";

//any underlying method can be called
stringUpper = S.toupper ();

//Error! Cannot assign numeric type data to a string type variable
s = -;
}
the role of implicitly typed local variables

Looking at the above introduction, you will certainly wonder what the use of this structure is. If it's just for the sake of simplicity, it's not worth it, because doing so might confuse other people who read the code. But when we use LINQ, the benefits of the Var keyword are apparent. It can dynamically create result sets based on the format of the query itself, so that we don't need to display the types that the definition query might return, and in many cases we don't see the return type of LINQ at a glance. The following example:

         Public   Static voidQueryoverints ()
{
int[] numbers = {Ten, -, -, +,1,2,3,5};
varsubset = from IinchNumberswhereI <TenSelect I;

Console.Write ("values in subset:");
foreach(varIinchsubset)
Console.Write ("{0}", i);
Console.WriteLine ();

Console.WriteLine ("subset is a: {0}", subset. GetType (). Name);
Console.WriteLine ("subset is defined in: {0}", subset. GetType (). Namespace);
}

Output:

In fact, we can assume that the var keyword is used only when defining the data returned from a LINQ query.

Automatic Properties

We know. NET language recommends using type attributes to encapsulate private data fields instead of using the getxxx () and Setxxx () methods. Because. NET base class libraries always use type properties instead of traditional access and modification methods, so using attributes can be obtained with the. NET platform for better integration. It is necessary to know that, at the bottom level, C # properties are mapped to the methods of prefixes get_ and set_, that is, if the Name attribute is defined, C # automatically generates the Get_name () and Set_name () methods.

Consider the following C # type definition:

    classPerson
{
Private stringFirstName =string. Empty;
Public stringFirstName
{
Get{returnFirstName; }
Set{firstName = value;}
}

Private stringLastName =string. Empty;
Public stringLastName
{
Get{returnLastName; }
Set{lastName = value;}
}

Private intLevel =0;
Public intLevel
{
Get{returnLevel }
Set{level = value;}
}
}

Although it is not difficult to define properties, it is cumbersome to define fields and properties on the secondary if the property is just an assignment and a return value, especially if the class properties are many. To simplify the process of encapsulating this simple data field, C # 3.0 provides automatic attribute syntax. Now, the person above can be defined in the following form:

    class Person
{
Public string Get set; }
Public string Get set; }
Public int Get set; }
}

When defining automatic attributes, we only need to specify access modifiers, data types, property names, and empty get/set scopes. At compile time, the automatically generated private support fields and the correct implementation of the Get/set logic are used.

It is important to note that when you define an automatic attribute, you must provide both the get and set keywords , so that you cannot define automatic properties that are read-only or write-only.

Anonymous Type

As an object-oriented programmer, we know how to define a class to express a given programming entity. When I need a type that is reused between projects, we typically create a C # class that provides the necessary set of properties, methods, and events for that class. But sometimes, we may need to define classes to encapsulate some related data without requiring any associated methods or events. Also, giving classes does not need to be reused across projects. Still, we have to define a "temporary" class that, while not very complex, will consume a lot of your working time if you need to define classes to encapsulate a lot of data members. I don't think anyone would want to turn programming into a mechanical exercise.

The anonymous type provided by C # 3.0 is for the above tasks, and the anonymous type is a natural extension of the anonymous method, which can help us to do the work above easily.

When defining an anonymous type, use the New keyword var and the object initialization syntax described earlier, as in the following example:

        Static voidTestanonymoustype ()
{
//constructs an anonymous object that represents an employee
varWorker =New{FirstName ="Vincent", LastName ="Ke", level =2};

//Display and Output
Console.WriteLine ("Name: {0}, Level: {1}", worker. FirstName +""+ worker. LastName, worker. level);
}

When you use the code above to build an anonymous object, the C # compiler automatically generates a class with the name unique at compile time. Because the name of this class is not visible in C #, it is necessary to use the VAR keyword to use implicit typing. In addition, we need to define a series of properties to encapsulate each data through the object initialization syntax.

internal representations of anonymous types

All anonymous types are automatically inherited from System.Object, and we can invoke the methods of ToString (), GetHashCode (), Equals (), GetType () on the worker of the implicitly typed word.

We can define the following methods for viewing anonymous types of information:

        Static voidReflectanonymoustype (ObjectObj
{
Console.WriteLine ("Type Name: {0}"Obj. GetType (). Name);
Console.WriteLine ("Base Class: {0}"Obj. GetType (). BaseType);
Console.WriteLine ("obj. ToString () = {0}"Obj. ToString ());
Console.WriteLine ("obj. GetHashCode () = {0}"Obj. GetHashCode ());
}

Static voidTestanonymoustype ()
{
//constructs an anonymous object that represents an employee
varWorker =New{FirstName ="Vincent", LastName ="Ke", level =2};
Reflectanonymoustype (worker);
}

The results are as follows:

In the example above, the type of worker is <>F__ANONYMOUSTYPE0 ' 3 (each version may be different), and the type name of the anonymous type is entirely determined by the compiler. More importantly, each name/value pair that is defined with the object initialization syntax is mapped to a read-only property with the same name and to the encapsulated private data member.

method ToString () and GetHashCode () the implementation

As you can see from the above, the anonymous type is directly System.Object and overrides the Equals (), GetHashCode (), and ToString () methods. where ToString () generates and returns a string based on each name/value pair, see.

The implementation of GetHashCode () computes the hash value using the member variable of each anonymous type. When and only if two anonymous types have the same attribute and are given the same value, the same hash value is generated, so that the anonymous type can work well with the Hashtable container.

equality semantics for anonymous types

The compiler-writable equals () uses value-based semantics when judging an object, but the compiler does not overload the equality operator (= = and! =), so using = = to compare two anonymous objects is a reference-based semantics! the "= =" Comparison reference is the default behavior for all classes. The following example:

        Static voidAnonymoustypeequalitytest ()
{
//build two anonymous types with the same name/value pairs
varWorker1 =New{FirstName ="Harry", Secondname ="Folwer", level =2};
varWorker2 =New{FirstName ="Harry", Secondname ="Folwer", level =2};

//equals Test
if(Worker1. Equals (Worker2))
Console.WriteLine ("worker1 equals Worker2");
Else
Console.WriteLine ("worker1 not equals Worker2");

//= = Test
if(Worker1 = = Worker2)
Console.WriteLine ("Worker1 = = Worker2");
Else
Console.WriteLine ("worker1! = Worker2");

//Type name Test
if(Worker1. GetType (). Name = = Worker2. GetType (). Name)
Console.WriteLine ("we are both the same type");
Else
Console.WriteLine ("we are different types");
}

The result is:

LINQ Route 2:c# 3.0 language features (top)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.