分享
 
 
 

C#.net

王朝百科·作者佚名  2009-12-21
窄屏简体版  字體: |||超大  

C#是一个语言,ASP.net是一个平台,上面支持用C#或者VB.Net写代码。

另外,C#不但可以开发基于ASP.net的应用程序,也可以开发基于WinForm的程序,这就是区别。

若是单纯以概念来说,你可以把.net当做一个工作平台一般,它是一个开发环境的基底,提供你开发Windows、Web、Mobile、XML...等应用程式一个共通的平台,若是要了解深一点,则再去了解其运作的相关机制那是有助于你利用它来开发.C#和.NET主要是应用在网际网路.

C#(读做C-sharp)编程语言是由微软公司的Anders Hejlsberg和 Scott Willamette领导的开发小组专门为.NET平台设计的语言,它可以使程序员移植到.NET上。这种移植对于广大的程序员来说是比较容易的,因为C#从C,C++和Java发展而来,它采用了这三种语言最优秀的特点,并加入了它自己的特性。C#是事件的驱动的,完全面向对象的可视化编程语言,我们可以使用集成开发环境来编写C#程序。使用IDE,程序员可以方便的建立,运行,测试和调试C#程序,这就将开发一个可用程序的时间减少到不用IDE开发时所用时间的一小部分。使用IDE迅速建立一个应用程序的过程称为快速反映开发。

C#2.0新特性

1、 泛型:在我看来,泛型就是通过将数据类型参数化从而实现了代码的更为灵活的复用,泛型的出现使得C#能够使用同一段代码来操作多种数据类型。泛型无疑是C#2.0最重大的改进,它的出现赋予了C#代码更强的类型安全,更好的复用,更高的效率和更清晰的约束。

2、 匿名方法:匿名方法允许我们将代码直接与委托实例相关联,使委托实例化工作更加直观和方便。在我看来,这只是C#又多了一种语法格式而已,不再像以前必须将方法名传给委托实例,而是又多了一种选择。

3、 迭代器:迭代器允许我们更加方便的编写用于foreach语句的类型。在我看来,迭代器的出现只不过是改进了1.0中不便的可用foreach语句类型的编写限制,简化了一些接口。

4、 局部类型:局部类型允许我们将一个类的代码分别写在不同的cs文件中。最典型的应用就是使用VS2005创建Form文件时,VS会自动将系统生成的代码与用户代码分开。局部类型通过partial关键字来声明。

5、 空属类型:空属类型是一种像int?一样可以为空的变量类型。本质上是一种泛型的应用,是System .Nullable<>的一种类型实例化。

6、 静态类:静态类是只用于包含静态成员的类型,它既不能实例化,亦不能被继承。

C#3.0中的新特性

第一个特性:隐式类型化本地变量

这个特性非常简单,有些JavaScript的影子,我们可以统一使用使用"var"关键字来声明局部变量,而不再需要指明变量的确切类型了,变量的确切类型可通过声明变量时的初始值推断出来。这样一来,可以大大简化我们声明局部变量的工作量了,下面是一个例子:

class LocalVariables : AppRunner.AbstractApplication

{

public override void Run()

{

var intValue = 5;

var stringValue = "This is a string";

var customClass = new LocalVariables();

var intArray = new int[3] { 1, 2, 3 };

foreach (var value in intArray)

Console.WriteLine(value);

}

}

上面的代码将被解析成:

class LocalVariables : AppRunner.AbstractApplication

{

public override void Run()

{

int intValue = 5;

string stringValue = "This is a string";

LocalVariables customClass = new LocalVariables();

int[] intArray = new int[3];

foreach (int value in intArray)

Console.WriteLine(value);

}

}

要特别注意的是,由于变量的类型是通过变量初始值推断而来的,所以在声明变量的同时必需为变量指定初始值。并且,变量并不是没有类型的,变量一旦初始化之后,类型就确定下来了,以后就只能存储某种类型的值了,比如上面的stringValue的类型经推断为string,所以该变量就只能保存string类型的值了。

第二个特性:匿名类型

有些时候我们需要临时保存一些运算的中间结果,特别是当这些中间结果是由多个部份组成时,我们常常会去声明一个新的类型,以方便保存这些中间结果。表面上看起来这很正常,而细想之后就会发现,这个新类型只服务于这个函数,其它地方都不会再使用它了,就为这一个函数而去定义一个新的类型,确实有些麻烦。

现在,C#3.0中的匿名类型特性就可以很好的解决上面提到的问题,通过匿名类型,我们可以简单使用new { 属性名1=值1, 属性名2=值2, ..... , 属性名n=值n }的形式直接在函数中创建新的类型,看下面这个例子:

class AnonymousType : AppRunner.AbstractApplication

{

public override void Run()

{

var anonymousType1 = new {

CardNumber = "10001", Name = "van’s", Sex = true

};

Console.WriteLine(anonymousType1.CardNumber);

Console.WriteLine(anonymousType1.Name);

var anonymousType2 = new {

CardNumber = "10002", Name = "martin", Sex = true

};

anonymousType2 = anonymousType1;

}

}

在新类型中只能有字段成员,而且这些字段的类型也是通过初值的类型推断出来的。如果在声明新的匿名类型时,新类型的字段名、顺序以及初始值的类型是一致的,那么将会产生相同的匿名类型,所以上例中anonymousType1和anonymousType2的类型是相同的,自然能进行anonymousType2=anonymousType1的赋值。

第三个特性:隐式类型化数组

这个特性是对隐式类型化本地变量的扩展,有了这个特性,将使我们创建数组的工作变得简单。我们可以直接使用"new[]"关键字来声明数组,后面跟上数组的初始值列表。在这里,我们并没有直接指定数组的类型,数组的类型是由初始化列表推断出来的。

class AnonymousTypeArray : AppRunner.AbstractApplication

{

public override void Run()

{

var intArray = new[] { 1, 2, 3, 4, 5 };

var doubleArray = new[] { 3.14, 1.414 };

var anonymousTypeArray = new[] {

new { Name="van’s", Sex=false, Arg=22 },

new { Name="martin", Sex=true, Arg=23 }

};

Console.WriteLine(intArray);

Console.WriteLine(doubleArray);

Console.WriteLine(anonymousTypeArray[0].Name);

}

}

上面的代码中,anonymousTypeArray变量的声明同时运用了隐式类型化数组和匿名类型两种特性,首先创建匿名类型,然后再初始值列表,推断出数组的确切类型。

第四个特性:对象构造者

我们在声明数组时,可以同时对其进行初始化,这样就省去了很多麻烦,但是在创建类的对象时,这招可就不灵了,我们要么调用该类的构造函数完成对象的初始化,要么就手工进行初始化。这两种方法都不太方便,使用构造函数来对对象进行初始化时,我们为了某种灵活性,可能需要编写构造函数的多个重载版本,实在是麻烦。

C#3.0中加入的对象构造者特性,使得对象的初始化工作变得格外简单,我们可以采用类似于数组初始化的方式来初始化类的对象,方法就是直接在创建类对象的表达式后面跟上类成员的初始化代码。具体示例如下:

class Point

{

public int X { get; set; }

public int Y { get; set; }

public override string ToString()

{

return "(" + X.ToString() + ", " + Y.ToString() + ")";

}

}

class Rectangle

{

public Point P1 { get; set; }

public Point P2 { get; set; }

public Rectangle()

{

P1 = new Point();

P2 = new Point();

}

public override string ToString()

{

return "P1: " + P1 + ", P2: " + P2;

}

}

class ObjectBuilder : AppRunner.AbstractApplication

{

public override void Run()

{

Point thePoint = new Point() { X = 1, Y = 2 };

Console.WriteLine("Point(X, Y) = ", thePoint);

Rectangle theRectangle = new Rectangle() {

P1 = { X = 1, Y = 1 }, P2 = { X = 100, Y = 200 }

};

Console.WriteLine(theRectangle);

}

}

我们在定义Point类的X和Y属性时,只须写上该属性的get和set访问器声明,C#编译器会自动为我们生成默认的get和set操作代码,当我们需要定义简单属性时,这个特性非常有用。

我们以new Point() { X = 1, Y = 2 }语句,轻松的完成了对Point类的初始化工作。在创建类的对象时,我们可以按照需要去初始化类的对象,只要在类的创建表达式后跟上要初始化属性的列表即可,且可以只对需要初始化的属性赋初值,而无需把所有属性的初始值都写上去。

在theRectangle对象的初始化表达式中,我们首先对P1属性进行初始化,然而P1属性也是一个自定义的类型,所以P1属性的初始化是另一个类型(Point)的初始化表达式,我们可以这样的方式来对更加复杂的类型进行初始化。

上篇文章中介绍了C# 3.0中比较简单的四个特性,分别是隐式类型化本地变量、匿名类型、隐式类型化数组,以及对象构造者,下面我将对C# 3.0中的较复杂,同时也是非常强大的几个特性进行介绍,供大家快速浏览。

第五个特性:集合构造者

我们可以在声明数组的同时,为其指定初始值,方法是直接在数组声明的后面跟上初始值列表。这样就使数组的初始化工作变得简单,而对于我们自己创建的集合类型,就无法享受到与普通数组一样的待遇了,我们无法在创建自定义集合对象的同时,使用数组的初始化语法为其指定初始值。

C# 3.0中加入的集合构造者特性,可使我们享受到与普通数组一样的待遇,从而在创建集合对象的同时为其指定初始值。为了做到这一点,我们需要让我们的集合实现ICollection<T>接口,在这个接口中,完成初始化操作的关键在于Add函数,当我使用初始化语法为集合指定初始值时,C#编译器将自动调用ICollection<T>中的Add函数将初始列表中的所有元素加入到集合中,以完成集合的初始化操作。使用示例如下:

class CollectionInitializer : AppRunner.AbstractApplication

{

class StringCollection : ICollection<string>

{

public void Add(string item)

{

Console.WriteLine(item);

}

// Other ICollection<T> Members

}

public override void Run()

{

StringCollection strings = new StringCollection() { "Van's", "Brog", "Vicky" };

}

}

在这个示例中,编译器会自动为strings对象调用Add方法,以将初始值列表中的所有元素加入到集合中,这里我们只是简单将初始值列表中的元素输出到控制台。

第六个特性:Lambda表达式

C# 2.0中加入的匿名代理,简化了我们编写事件处理函数的工作,使我们不再需要单独声明一个函数来与事件绑定,只需要使用delegate关键字在线编写事件处理代码。

而C# 3.0则更进一步,通过Lambda表达式,我们可以一种更为简洁方式编写事件处理代码,新的Lambda事件处理代码看上去就像一个计算表达式,它使用"=>"符号来连接事件参数和事件处理代码。我可以这样写:SomeEvent += 事件参数 => 事件处理代码;下面是完整的示例:

delegate T AddDelegate<T>(T a, T b);

class LambdaExpression : AppRunner.AbstractApplication

{

public static event EventHandler MyEvent;

public override void Run()

{

MyEvent += delegate(object s, EventArgs e)

{

Console.WriteLine(s);

};

MyEvent += (s, e) => { Console.WriteLine(s); };

MyEvent(this, null);

AddDelegate<string> add = (a, b) => a + b;

Console.WriteLine(add("Lambda", "Expression"));

}

}

在上面的例子中,分别使用了匿名代理和Lambda表达式来实现同样的功能,可以明显看出Lambda表达式的实现更为简洁。我们在使用Lambda表达式编写事件处理代码时,无需指明事件参数的类型,且返回值就是最后一条语句的执行结果。

第七个特性:扩展方法

当我们需要对已有类的功能进行扩展时,我们通常会想到继承,继承已有类,然后为其加入新的行为。而C# 3.0中加入的扩展方法特性,则提供了另一种实现功能扩展的方式,我们可以在不使用继承的前提下实现对已有类本身的扩展,这种方法并不会产生新的类型,而是采用向已有类中加入新方法的方式来完成功能扩展。

在对已有类进行扩展时,我们需将所有扩展方法都写在一个静态类中,这个静态类就相当于存放扩展方法的容器,所有的扩展方法都可以写在这里面。而且扩展方法采用一种全新的声明方式:public static 返回类型 扩展方法名(this 要扩展的类型 sourceObj [,扩展方法参数列表]),与普通方法声明方式不同,扩展方法的第一个参数以this关键字开始,后跟被扩展的类型名,然后才是真正的参数列表。下面是使用示例:

static class Extensions

{

public static int ToInt32(this string source)

{

return Int32.Parse(source);

}

public static T[] Slice<T>(this T[] source, int index, int count)

{

if (index < 0 || count < 0 || index + count > source.Length)

{

throw new ArgumentException();

}

T[] result = new T[count];

Array.Copy(source, index, result, 0, count);

return result;

}

}

class ExtensionMethods : AppRunner.AbstractApplication

{

public override void Run()

{

string number = "123";

Console.WriteLine(number.ToInt32());

int[] intArray = new int[] { 1, 2, 3 };

intArray = intArray.Slice(1, 2);

foreach (var i in intArray)

Console.WriteLine(i);

}

}

在上面的示例中,静态的Extensions类中有两个扩展方法,第一个方法是对string类的扩展,它为string类加入了名为ToInt32的方法,该方法没有参数,并返回一个int类型的值,它将完成数字字符向整数的转换。有了这个扩展方法之后,就可对任意string类的对象调用ToInt32方法了,该方法就像其本身定义的一样。

第二个扩展方法是一个范型方法,它是对所有数组类型的扩展,该方法完成数组的切片操作。

C# 3.0中的Linq表达式,就是大量运用扩展方法来实现数据查询的。

第八个特性:Linq查询表达式

C# 3.0中加入的最为复杂的特性就是Linq查询表达式了,这使我们可直接采用类似于SQL的语法对集合进行查询,这就使我们可以享受到关系数据查询的强大功能。

Linq查询表达式是建立在多种C# 3.0的新特性之上的,这也是我为什么最后才介绍Linq的原因。下面看一个例子:

class LinqExpression : AppRunner.AbstractApplication

{

public override void Run()

{

// 定义匿名数组persons, 并为其赋初值

var persons = new[] {

new { Name="Van's", Sex=false, Age=22 },

new { Name="Martin", Sex=true, Age=30 },

new { Name="Jerry", Sex=false, Age=24 },

new { Name="Brog", Sex=false, Age=25 },

new { Name="Vicky", Sex=true, Age=20 }

};

/*

执行简单Linq查询

检索所有年龄在24岁以内的人

查询结果放在results变量中

results变量的类型与数组persons相同

*/

var results = from p in persons

where p.Age <= 24

select p;

foreach (var person in results)

{

Console.WriteLine(person.Name);

}

Console.WriteLine();

// 定义匿名数组customers, 并为其赋初值

// 该数组是匿名类型的

var customers = new[] {

new {

Name="Van's", City="China", Orders=new[] {

new {

OrderNo=0,

OrderName="C# Programming Language(Second Edition)",

OrderDate=new DateTime(2007,9, 5)

},

new {

OrderNo=1,

OrderName="Head First Design Patterns(Chinese Edition)",

OrderDate=new DateTime(2007,9,15)

},

new {

OrderNo=2,

OrderName="ASP.NET Unleashed 2.0(Chinese Edition)",

OrderDate=new DateTime(2007,09,18)

},

new {

OrderNo=3,

OrderName="The C++ Programming Langauge(Special Edition)",

OrderDate=new DateTime(2002, 9, 20)

}

}

},

new {

Name="Brog", City="China", Orders=new[] {

new {

OrderNo=0,

OrderName="C# Programming Language(Second Edition)",

OrderDate=new DateTime(2007, 9, 15)

}

}

},

new {

Name="Vicky", City="London", Orders=new[] {

new { OrderNo=0,

OrderName="C++ Programming Language(Special Edition)",

OrderDate=new DateTime(2007, 9, 20)

}

}

}

};

/*

执行多重Linq查询

检索所在城市为中国, 且订单日期为2007年以后的所有记录

查询结果是一个匿名类型的数组

其中包含客户名, 订单号, 订单日期, 订单名四个字段

*/

var someCustomers = from c in customers

where c.City == "China"

from o in c.Orders

where o.OrderDate.Year >= 2007

select new { c.Name, o.OrderNo, o.OrderDate, o.OrderName };

foreach (var customer in someCustomers)

{

Console.WriteLine(

customer.Name + ", " + customer.OrderName + ", " +

customer.OrderDate.ToString("D")

);

}

}

}

从上面的例子中,我们可以看到Linq查询的强大特性,它允许我们进行简单查询,或者进行更为复杂的多重连接查询。且查询的结果还可以是自定义的匿名类型。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有