[翻译]LINQ Project: Unified Language Features for Object and Relational Queries(2)

Exercise 1 –LINQ for In-Memory Collections

练习1-内存集合的LINQ

In this exercise, you learn how to query over object sequences.  Any collection supporting the System.Collections.Generic.IEnumerable interface or the generic interface IEnumerable<T> is considered a sequence and can be operated on using the new LINQ standard query operators.  Standard query operators allow programmers to construct queries including projections that create new types on the fly. This goes hand-in-hand with type inference, a new feature that allows local variables to be automatically typed by their initialization expression.

这些练习中,你将学到如何查询对象序列。任何集合支持System.Collections.Generic.IEnumerable接口或者范型接口IEnumerable<T>处理的序列和能被新LINQ标准查询操作器操作的集合。

Task 1 – Creating the “LINQ Overview” Solution

1.  Click the Start | Programs | Microsoft Visual Studio 2008 | Microsoft Visual Studio 2008 menu command.

2.  Click the File | New | Project… menu command.

3.  In the New Project dialog box select the Visual C# Windows project type.

4.  Select the Console Application template.

5.  Provide a name for the new project by entering “LINQ Overview” in the Name box.

6.  Click OK.

Task 2 – Querying a Generic List of Integers

1.  In Solution Explorer, double click Program.cs

2.  Create a new method that declares a populated collection of integers (put this method in the Program class):

class Program

{

    static void Main(string[] args)

    {

    }

    static void NumQuery()

    {

        var numbers = new int[] { 1, 4, 9, 16, 25, 36 };

    }

}

 

Notice that the left-hand side of the assignment does not explicitly mention a type; rather it uses the new keyword var.  This is possible due to one of the new features of the C# 3.0 language, implicitly typed local variables.  This feature allows the type of a local variable to be inferred by the compiler.  In this case, the right-hand side creates an object of type Int32[]; therefore the compiler infers the type of the numbers variable to be Int32[]. This also allows a type name to be specified only once in an initialization expression.

注意左手边的委派没有明确的涉及到一个类型;反而它使用一个新关键则var。这些可能归结于C#3.0的一个新特性,隐含类型的本地变量。这特性允许一个本地变量类型在编译时判断出来。在这些案例中,右手边创建一个Int32[]类型对象;因此编译器推断出是一个Int32[]的数字类型变量。同时也仅允许类型名称在初始化表达式中指定一次。

3.  Add the following code to query the collection for even numbers

在增加下列代码为查询集合中的偶数

static void NumQuery()

{

var numbers = new int[] { 1, 4, 9, 16, 25, 36 };

       

var evenNumbers = from p in numbers

                        where (p % 2) == 0

                        select p;

}

 

In this step the right-hand side of the assignment is a query expression, another language extension introduced by the LINQ project.  As in the previous step, type inference is being used here to simplify the code.  The return type from a query may not be immediately obvious.  This example returns System.Collections.Generic.IEnumerable<Int32>; move the mouse over the evenNumbers variable to see the type in Quick Info.  Indeed, sometimes there will be no way to specify the type when they are created as anonymous types (which are tuple types automatically inferred and created from object initalizers).  Type inference provides a simple solution to this problem.

在这些步骤中右手边委派了介绍LINQ项目扩展的另一种语言表达式的查询表达式。同样在以前的步骤中type inference(类型推断)的使用令代码简单化。从查询中可能不会很快得知返回类型。这些例子返回System.Collections.Generic.IEnumerable<Int32>类型;移动鼠标到evenNumbers变量可以从Quick Info(快速信息)中看到它的类型。确实,当他们被创建的时候将会作为一个匿名类型而不会被指定(那些类型将在他们创建时的对象初始化中自动推断指定)type inference(类型推断)提供问题的简单解决方案。

4.  Add the following code to display the results:增加下列代码显示结果:

static void NumQuery()

{

  var numbers = new int[] { 1, 4, 9, 16, 25, 36 };

        

  var evenNumbers = from p in numbers

                        where (p % 2) == 0

                        select p;

 

        Console.WriteLine("Result:");

        foreach (var val in evenNumbers)

          Console.WriteLine(val);

}

 

Notice that the foreach statement has been extended to use type inference as well. 

注意:foreach声明使用很好的扩展了类型推断

5.  Finally, add a call to the NumQuery method from the Main method:

static void Main(string[] args)

{

    NumQuery();

}

 

6.  Press Ctrl+F5 to build and run the application.  A console window appears.  As expected all even numbers are displayed (the numbers 4, 16, and 36 appear in the console output).

7.  Press any key to terminate the application.

Task 3 – Querying Structured Types

1.  In this task, you move beyond primitive types and apply query features to custom structured types.  Above the Program class declaration, add the following code to create a Customer  class:

在这步中,你移除原始类型并且应用查询功能的自定义结构体类型。在Program类声明上增加下列代码创建Customer

public class Customer

{

    public string CustomerID { get; set; }

    public string City { get; set; }

 

    public override string ToString()

    {

        return CustomerID + "\t" + City;

    }

}

class Program

 

Notice the use of another new C# language feature, auto-implemented properties.  In the preceding code, this feature creates two properties with automatic backing fields.  Also notice that no constructor has been declared.  In earlier versions of C#, this would have required consumers to create an instance of the object using the default parameterless constructor and then set the fields explicitly as separate statements. 

注意使用了C#语言的其他新功能,自动执行属性(auto-implemented property)。在前面的代码中,这些功能使用自动支持字段创建两个属性。同样也注意没有结构体被声明。在早期C#版本中,这些单词需要用户创建对象实例时使用默认参数构造器,并且使用明确声明的设置字段。

2.  Within the Program class declaration, create the following new method, which creates a list of customers (taken from the Northwind database):

static void Main(string[] args)

{

    NumQuery();

}

static IEnumerable<Customer> CreateCustomers()

{

    return new List<Customer>

    {

        new Customer { CustomerID = "ALFKI", City = "Berlin"    },

        new Customer { CustomerID = "BONAP", City = "Marseille" },

        new Customer { CustomerID = "CONSH", City = "London"    },

        new Customer { CustomerID = "EASTC", City = "London"    },

        new Customer { CustomerID = "FRANS", City = "Torino"    },

        new Customer { CustomerID = "LONEP", City = "Portland"  },

        new Customer { CustomerID = "NORTS", City = "London"    },

        new Customer { CustomerID = "THEBI", City = "Portland"  }   

    };

}       

 

There are several interesting things to note about this code block.  First of all, notice that the new collection is being populated directly within the curly braces.  That is, even though the type is List<T>, not an array, it is possible to use braces to immediately add elements without calling the Add method.  Second, notice that the Customer elements are being created with a new syntax (known as object initializers).  Even though there is no constructor with two parameters for the Customer class, it is possible to create objects of that class as expressions by setting its properties explicitly inside curly braces.   

这个代码块中有几个有趣的东西需要注意。首先,请注意,新的集合直接在大括号中被填充。也就是,即使该类型是List <T>,不是数组,它是可以使用大括号立即添加元素而不调用 Add 方法。其次,请注意,客户元素被用一种新的语法 (称为对象初始化表达式) 创建。尽管没有构造函数具有两个参数为 Customer 类,很可能通过设置其属性显式在大括号来创建该类别的对象作为表达式。

3.  Next query the collection for customers that live in London.  Add the following query method ObjectQuery and add a call to it within the Main method (removing the call to StringQuery). 

static void ObjectQuery()

{

    var results = from c in CreateCustomers()

      where c.City == "London"

        select c;

 

    foreach (var c in results)

        Console.WriteLine(c);

}

 

static void Main(string[] args)

{

    ObjectQuery();

}

 

Notice that again the compiler is using type inference to strongly type the results variable in the foreach loop.

请注意,再次编译器是使用类型推断(type inference)以强类型返回 foreach 循环变量。

4.  Press Ctrl+F5 to build and run the application.  After viewing the results, press any key to terminate the application.

 

Three results are shown.  As you can see, when using LINQ query expressions, working with complex types is just as easy as working with primitive types.

显示的三种结果。  正如您看到,使用 LINQ 查询表达式时,复杂类型使用就像使用基元类型一样简单。
posted @ 2007-11-19 14:54  cspfeng  阅读(277)  评论(0编辑  收藏  举报
测试