您的位置:首页 > 编程语言 > C#

C# 经典语法

2016-12-26 17:29 155 查看


1)async / await

使用async / await-pattern允许在执行阻塞操作时解除UI /当前线程的阻塞。async / await-pattern的工作原理是让代码继续执行,即使在某些东西阻塞了执行(如Web请求)的情况下。

阅读更多有关async / await-pattern的信息,请访问:https://msdn.microsoft.com/en-us/library/hh191443.aspx


2)对象/数组/集合初始化器

通过使用对象、数组和集合初始化器,可以轻松地创建类、数组和集合的实例:
//一些演示类
public class Employee {
public string Name {get; set;}
public DateTime StartDate {get; set;}
}

//使用初始化器创建employee 
Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()};


上面的例子在单元测试中才真正有用,但在其他上下文中应该避免,因为类的实例应该使用构造函数创建。

阅读更多有关初始化器的信息,请访问:https://msdn.microsoft.com/en-us/library/bb384062.aspx


3)Lambdas,谓词,delegates和闭包

在许多情况下(例如使用Linq时),这些功能实际上是必需的,确保学习何时以及如何使用它们。

阅读更多关于Lambdas,谓词,delegates和闭包的信息,请访问:http://www.codeaddiction.net/articles/13/lambda-expressions-delegates-predicates-and-closures-in-c


4)??(空合并运算符)

?? – 运算符返回左侧,只要它不为null;那样的情况下返回右侧:
//可能为null
var someValue = service.GetValue();
var defaultValue = 23

//如果someValue为null,结果将为23
var result = someValue ?? defaultValue;


?? – 运算符可以链接:
string anybody = parm1 ?? localDefault ?? globalDefault;


并且它可以用于将可空类型转换为不可空:
var totalPurchased = PurchaseQuantities.Sum(kvp => kvp.Value ?? 0);


阅读更多有关?? – 运算符的信息,请访问:https://msdn.microsoft.com/en-us/library/ms173224.aspx


5)$“{x}”(字符串插值) ——C#6

这是C#6的一个新功能,可以让你用高效和优雅的方式组装字符串:
//旧方法
var someString = String.Format("Some data: {0}, some more data: {1}", someVariable, someOtherVariable);

//新方法
var someString = $"Some data: {someVariable}, some more data: {someOtherVariable}";


你可以把C#表达式放在花括号之间,这使得此字符串插值非常强大。


6)?.(Null条件运算符) ——C#6

null条件运算符的工作方式如下:
//Null if customer or customer.profile or customer.profile.age is null
var currentAge = customer?.profile?.age;


没有更多NullReferenceExceptions!

阅读更多有关?.-运算符的信息,请访问:https://msdn.microsoft.com/en-us/library/dn986595.aspx


7)nameof Expression ——C#6

新出来的nameof-expression可能看起来不重要,但它真的有它的价值。当使用自动重构因子工具(如ReSharper)时,你有时需要通过名称引用方法参数:
public void PrintUserName(User currentUser)
{
//The refactoring tool might miss the textual reference to current user
below if we're renaming it
if(currentUser == null)
_logger.Error("Argument currentUser is not provided");

//...
}


你应该这样使用它…
public void PrintUserName(User currentUser)
{
//The refactoring tool will not miss this...
if(currentUser == null)
_logger.Error($"Argument {nameof(currentUser)} is not provided");

//...
}


阅读更多有关nameof-expression的信息,请访问:https://msdn.microsoft.com/en-us/library/dn986596.aspx


8)属性初始化器 ——C#6

属性初始化器允许你声明属性的初始值:
public class User
{
public Guid Id { get; } = Guid.NewGuid();
// ...
}


使用属性初始化器的一个好处是你不能声明一个集合:嗯,因此使得属性不可变。属性初始化器与C#6主要构造函数语法一起工作。


9)as和is 运算符

is 运算符用于控制实例是否是特定类型,例如,如果你想看看是否可能转换:
if (Person is Adult)
{
//do stuff
}


使用as运算符尝试将实例转换为类。如果不能转换,它将返回null:
SomeType y = x as SomeType;
if (y != null)
{
//do stuff
}


10)yield 关键字

yield 关键字允许提供带有条目的IEnumerable接口。 以下示例将返回每个2的幂,幂指数从2到8(例如,2,4,8,16,32,64,128,256):
public static IEnumerable Power(int number, int exponent)
{
int result = 1;
for (int i = 0; i < exponent; i++)
{
result = result * number;
yield return result;
}
}


yield返回可以非常强大,如果它用于正确方式的话。 它使你能够懒惰地生成一系列对象,即,系统不必枚举整个集合——它就会按需完成。


11、readonly 关键字与 const 关键字不同

readonly 关键字与 const 关键字不同。const 字段只能在该字段的声明中初始化。readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。另外,const 字段是编译时常数,而 readonly 字段可用于运行时常数


12、equal :比较值 (数字不可用) ==:比较内存地址 (数字是比较值) 

  public class EqualTest { 
public static void main(String[] args) { 

    //对于基本类型的变量。"=="和"equal"的区别 
    int t1=57; 

    int t2=67; 

    int t3=124; 

    int t4=124; 

     

    //“==”对于基本数据类型,判断两个变量的值是否相等。 

    Boolean result1=(t1==t2); 

    Boolean result2=((t1+t2)==t3); 

    Boolean result3=(t3==t4); 

     

    System.out.println("/n/n-----【t1==t2】"+result1+"/n-----【(t1+t2)=t3】"+result2+"/n-----【t3=t4】"+result3); 

    //“equal”不能用于基本数据类型。只能用于类变量。对于基本数据类型要用其包装类。 
    Integer i1=new Integer(t1); 

    Integer i2=new Integer(t2); 

    Integer i3=new Integer(t3); 

    Integer i4=new Integer(t4); 

     

     

    Boolean ri1=i1.equals(i2); 

    Boolean ri2=i3.equals(i1+i2); 

    Boolean ri3=i3.equals(i4); 

     

    System.out.println("/n/n-----【i1.equals(i2)】"+ri1+"/n-----【i3.equals(i1+i2)】"+ri2+"/n-----【i3.equals(i4)】"+ri3); 

   

    //对于对象变量,"=="和"equal"的区别 
    String st1="wasiker "; 

    String st2="is super man"; 

    String st3="wasiker is super man"; 

    String st4="wasiker is super man"; 

     

    Boolean b1=(st1==st2); 

    Boolean b2=(st1+st2)==st3; 

    Boolean b3=(st3==st4); 

     

    System.out.println("/n/n-----【st1==st2】"+b1+"/n-----【(st1+st2)==st3】"+b2+"/n-----【st3==st4】"+b3); 

//因为对象变量的存储的是对象在内存中的路径,即内存地址。所以用“==”比较时,即使 
//对象的值相等,但是他们的内存地址不同,所以==的结果为false。故“==”用于比较两 
//个变量的值是否相等,而不是变量引用的对象是否相等 

    Boolean r1=st1.equals(st2); 

    Boolean r2=(st1+st2).equals(st3); 

    Boolean r3=st3.equals(st4); 

     

    System.out.println("/n/n-----【st1.equals(st2)】"+r1+"/n-----【(st1+st2).equals(st3)】"+r2+"/n-----【st3.equals(st4)】"+r3); 

//equal用于比较两个对象是否相同。 



运行结果为: 
-----【t1==t2】false 

-----【(t1+t2)=t3】true 

-----【t3=t4】true 

-----【i1.equals(i2)】false 

-----【i3.equals(i1+i2)】true 

-----【i3.equals(i4)】true 

-----【st1==st2】false 

-----【(st1+st2)==st3】false 

-----【st3==st4】true 

-----【st1.equals(st2)】false 

-----【(st1+st2).equals(st3)】true 

-----【st3.equals(st4)】true 

总之: 
“==”比较的是值【变量(栈)内存中存放的对象的(堆)内存地址】 
equal用于比较两个对象的值是否相同【不是比地址】 

【特别注意】Object类中的equals方法和“==”是一样的,没有区别,而String类,Integer类等等一些类,是重写了equals方法,才使得equals和“==不同”,所以,当自己创建类时,自动继承了Object的equals方法,要想实现不同的等于比较,必须重写equals方法。

"=="比"equal"运行速度快,因为"=="只是比较引用.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: