还记得 千年虫问题? 显然,由于全球计算机网络的混乱,世界末日即将来临. 就在一年前, 我们听说1999年将标志着世界末日,因为它的名字中有一个颠倒的666. 在如此动荡的时代, 那时很多人都在地下室堆食物, 希望世界末日不会发现他们, 有几个有远见的人仍然在发明一些很酷的东西. 其中一个是 理论上来说, 是谁召集了一个微软开发团队并创造了“酷”, 哪一个是新的c类面向对象语言的第一个版本, 后来被命名为c#(发音为“C Sharp”).
14年后的5个版本之后,c#成为了业界最流行的语言之一. 尽管事实是 詹姆斯·高斯林 和 比尔快乐 声称c#只是对Java的模仿, 而其他一些批评人士甚至称c#是缺乏创新的无聊重复, c#现在在全世界数以百万计的开发人员所使用的所有其他平台中是站得很高的.
c#是一种包含强类型的多范式编程语言, 也很重要, 声明, 功能, 通用的, 面向对象(基于类), 以及面向组件的编程原则. 您可以使用它来构建任何类型的应用程序, 无论是服务, 控制台, 桌面, 网络甚至智能手机应用程序.
每种应用程序类型都需要一套标准c#语法之上的特定技能, 以及找到一个优秀的c#程序员, 无论是全职还是兼职, 这不是一件容易的事吗. 如果你正在寻找一个web开发人员,你应该期待在HTTP协议的技术专家, Web表单, MVC框架和剃刀视图引擎, 而其他一些应用程序将有其自身的挑战.
这篇文章应该可以帮助你找到一个理解c#核心的开发人员. 无论应用程序类型如何, 下面提到的技术和技巧应该对所有c#开发专家都是通用的,并且他们都应该能够展示对这些主题的广泛理解.
我将尝试介绍每个开发人员都必须了解的一般主题. 本文的目的是指出几个特定的主题. 深入评估每一种知识需要的远远不止一两个问题.

泛型
泛型是c#语言最早的特性之一. 泛型使设计类和方法成为可能,它们将一个或多个类型的规范推迟到类或方法被客户端代码声明和实例化之后.
Q:考虑下面的代码,它是控制台应用程序的一部分:
Main(string[] args)
{
= new 开发人员List();
IntegerList listOfNumbers = new IntegerList();
listOfNumbers.DoSomething (5);
listOf开发人员.DoSomething(新开发人员());
}
公共类开发人员
{
public string Name { get; set; }
public List 技能 { get; set; }
}
公开课开发人员List
{
public void DoSomething(开发者)
{
控制台.WriteLine(“与开发者一起做事”);
}
}
公开课IntegerList
{
public void DoSomething(Int32 number)
{
控制台.WriteLine(“用数字做事情”);
}
}
以替换的方式优化代码 开发人员List
和 IntegerList
其中一个类名为 GenericList
它将包含single doSomething
方法. 一定要在什么时候处理这个案子 GenericList
由意外类型实例化.
解决方案应该类似如下:
Main(string[] args)
{
GenericList listOfNumbers = new GenericList();
GenericList<开发人员> listOf开发人员 = new GenericList<开发人员>();
GenericList listOfStrings = new GenericList();
listOfNumbers.DoSomething (5);
listOf开发人员.DoSomething(新开发人员());
listOfStrings.DoSomething(“什么”);
}
公共类开发人员
{
public string Name { get; set; }
public List 技能 { get; set; }
}
class GenericList
{
public void DoSomething(T 价值){
如果(值.方法()= = typeof (Int32))
{
控制台.WriteLine(“做某事”);
返回;
}
如果(值.方法()= = typeof(开发人员)
{
控制台.WriteLine(“与开发者一起做事”);
返回;
}
控制台.WriteLine(“我不能做任何事情”+值.方法().ToString ());
}
}
LINQ
LINQ(语言集成查询)是c#中最酷的特性之一. 它是在Visual Studio 2008中引入的,它为c#提供了非常强大的查询功能. LINQ引入了用于查询和更新数据的标准模式,支持任何类型的数据存储.
或者,简单地说,LINQ支持对c#中的对象集合进行类似sql的查询.
问:假设你有一个类 开发人员
定义是这样的:
类开发人员
{
public string Name { get; set; }
public List 技能 { get; set; }
}
编写一段代码,将所有具有“SQL”技能的开发人员从 List<开发人员> 开发人员s
.
对于一个理解LINQ的开发者,你所期望得到的答案可能是这样的:
Var结果= from d in 开发人员,其中d.技能.包含(“SQL”)选择d;
不习惯LINQ的开发人员可能会使用标准的迭代方法 为
, 为each
or 而
结合 if
. 类似于:
var 结果 = new List<开发人员>();
Foreach(开发者中的var d)
{
如果(d.技能.包含(“SQL”))
结果.添加(d);
}
尽管这是一个技术上正确的解决方案, 由于代码的复杂性,这种方法不太理想.
Lambda表达式
Lambda表达式是不需要声明的方法. 这些是与其余代码“内联”实现的函数. Lambda表达式对于编写LINQ查询表达式特别有帮助.
创建lambda表达式, you specify input parameters (if any) on the left side of the lambda operator =>, 然后你把表达式或语句块放在另一边. 例如,lambda表达式 x => x * x
指定一个名为 x
并返回值 x
的平方.
lambda表达式的一般定义是:
(parameters) => Code
Q:通过实现这些方法来完成下面的代码 广场
和 双
基于 计算
委托和lambda表达式.
计算(int输入);
Main(string[] args)
{
int 价值1 = 广场(5);
int 价值2 = 双(5);
控制台.WriteLine (价值1);
控制台.WriteLine (价值2);
控制台.ReadLine ();
}
预期的解决方案应该很简单,只需添加两行代码:
计算(int输入);
Main(string[] args)
{
计算 广场 = x => x * x; // NEW
计算 双 = x => x * 2; // NEW
int 价值1 = 广场(5);
int 价值2 = 双(5);
控制台.WriteLine (价值1);
控制台.WriteLine (价值2);
控制台.ReadLine ();
}
的 计算
委托声明为返回 Int
并接受一个 Int
作为一个参数,所以 广场
和 双
方法只是实现了正确的计算.
命名参数
命名参数使您不必记住或查找被调用方法的参数列表中的参数顺序. 每个参数的参数可以通过参数名指定.
考虑以下代码:
Main(string[] args)
{
控制台.WriteLine(权力(4, 3)); //64
控制台.WriteLine(权力(3, 4)); //81
}
静态双功率(双基数,双功率)
{
返回数学.战俘(baseNumber、电力);
}
对象的参数传递顺序 权力
方法 would produce a different result; 64 one way, versus 81 the other.
Q:更新上面的代码以产生相同的结果(4的3次方= 64),而不管传递给 权力
方法.
这个问题的解决方案是传递命名参数. 你得改变你打电话的方式 权力
.
控制台.WriteLine(权力(baseNumber: 4, power: 3)); //64
控制台.WriteLine(权力(power: 3, baseNumber: 4)); //64
您需要做的唯一一件事是在传入值时添加参数名.
可选参数
方法的定义, 构造函数, 索引器, 或委托可以指定其参数是必需的或可选的. 任何调用都必须为所有必需的参数提供实参, 但是可以省略可选参数的参数.
每个可选参数都有一个默认值作为其定义的一部分. 如果没有为该参数发送参数,则使用默认值.
可选参数定义在参数列表末尾,任何必需参数之后. 如果调用者为一系列可选参数中的任何一个提供参数, 它必须为前面的所有可选参数提供参数. 参数列表中不支持逗号分隔的空白.
问:扩展 开发人员
具有命名的布尔属性的 启用
和一个接受的构造函数 的名字
和可选的 启用
价值.
公共类开发人员
{
public string Name { get; set; }
public List 技能 { get; set; }
}
预期的解决办法是:
公共类开发人员
{
开发人员(string 的名字, bool 启用=true)
{
Name =名称;
启用=启用;
}
public string Name { get; set; }
public bool 启用 { get; set; }
public List 技能 { get; set; }
}
使用可选的 启用
参数示例如下:
开发人员 elvis = new 开发人员("Elvis"); //elvis.启用= true
开发人员 mick = new 开发人员("Mick", false); //mick.启用= false
异步处理
对于可能阻塞的活动来说,异步是必不可少的, 例如当您的应用程序访问网络资源时. 对网络资源的访问有时很慢或延迟. 如果这样的活动阻塞了同步进程,整个应用程序必须等待. 在异步进程中, 应用程序可以继续进行其他不依赖于网络资源的工作,直到可能阻塞的任务完成.
Visual Studio 2012引入了一种简化的方法, 异步编程, 的异步支持 .净框架4.5和窗户运行时. 编译器完成开发人员过去所做的困难工作, 您的应用程序保留了类似于同步代码的逻辑结构. 因此,只需少量的工作就可以获得异步编程的所有优点.
的 异步
和 等待
c#中的关键字是异步编程的核心. 通过使用这两个关键字,可以使用 .。净 Framework或窗户运行时创建异步方法几乎和创建同步方法一样简单. 通过使用定义的异步方法 异步
和 等待
被称为异步方法.
下面的例子展示了一个异步方法.
异步 任务 Access的WebAsync()
{
HttpClient client = new HttpClient();
任务 getString任务 = client.GetStringAsync (" http://www.eisstocksport.net”);
DoIndependentWork ();
string urlContents = 等待 getString任务;
返回urlContents.长度;
}
Q:以下代码的输出是什么? 解释你的答案.
静态字符串语句= "Start";
static 异步 任务 Say等待()
{
等待任务.延迟(5000);
声明=“等待”;
控制台.WriteLine(声明);
返回语句;
}
static 异步 任务 Say延迟()
{
线程.睡眠(1000);
声明=“延迟”;
控制台.WriteLine(声明);
返回语句;
}
Main(string[] args)
{
Say等待 ();
Say延迟 ();
控制台.写作线(“Final:”+ 声明);
控制台.ReadLine ();
}
在应用程序暂停5秒后,这段代码的输出将是:
延迟
最后:延迟
等待
注:第一个“延迟”将在延迟一秒后显示.
这样做的原因是阻碍 异步
方法是在c#中处理的,它们之间的区别是 任务.延迟
和 线程.睡眠
. 的 Say等待
方法将像任何其他方法一样执行,直到它到达 等待
comm和. 此时,c#将启动另一个线程来执行 任务.延迟
在新线程上,同时释放当前线程以继续下一个操作,即 Say延迟
. 在主线程休眠一秒钟后, Say延迟
将为 声明
然后继续执行剩下的命令, WriteLine
和 ReadLine
. 当这一切发生的时候, Say等待
将很好地暂停在自己的线程,并在5秒后,它将设置 声明
到“等待”,产生自己的输出,然后返回.
问:如果 声明= "等待"
将会在 等待
comm和? 解释你的答案.
static 异步 任务 Say等待()
{
声明=“等待”;
等待任务.延迟(5000);
控制台.WriteLine(声明);
返回语句;
}
在这种情况下,输出如下:
延迟
最后:延迟
延迟
这样做的原因是“等待”值被分配给 声明
之前 等待
命令被称为. 的时候 控制台.WriteLine(声明);
in Say等待
执行时,值为 声明
已经被 Say延迟
方法.
保持敏锐!
c#是web开发领域的新秀. 一开始它被忽视,然后被嘲笑,然后被反对. 现在,它继续赢得了全世界开发者的支持. 这种增长的直接结果是大量的开发人员正在使用c#代码.
本文引用了每个c#开发专家都应该掌握的主题. 当你在寻找优秀的c#开发人员时,请确保涵盖这些主题, 这样你就离发现精英中的精英更近了一步.