目录
介绍
使用代码
元组(带有类型和文字)
记录类型
最小化OUT
Non-“NULL”的引用类型
本地方法/函数
使用文字提高可读性
模式匹配
按Ref“return”
从表达式引发异常
注意事项
介绍C#7.0计划分批发布,Microsoft已发布其大多数功能以及Visual Studio“ 15” Preview 4,它于上个月(2016年8月)发布,请参见发布后。
代码简化和提高性能是此版本的主要关键作用,元组,模式匹配是其中引入的一些非常好的功能。希望您会喜欢这些功能并提高工作效率。
让我们看看C#7.0的新功能
使用代码 元组(带有类型和文字)从方法返回多个值现在是一种常见的做法,我们通常使用自定义数据类型,out参数,动态返回类型或元组对象,但是在这里C#7.0 为您带来了元组类型和元组文字,它只是返回元组对象的多个值/多个类型信息。见下面的片段
( string, string, string, string) getEmpInfo()
{
//read EmpInfo from database or any other source and just return them
string strFirstName = "abc";
string strAddress = "Address";
string strCity= "City";
string strState= "State";
return (strFirstName, strAddress, strCity, strState); // tuple literal
}
//Just call above method and it will return multiple values
var empInfo= getEmpInfo();
WriteLine("Emp info as {empInfo .Item1} {empInfo .Item2} {empInfo .Item3} {empInfo .Item4}.");
在上面的示例中,我们可以轻松地从元组中检索多个值,但是Item1,Item2名称与位无关,因此让我们在返回之前分配一些有意义的名称,请参见以下示例
(string strFName, string strAdd, string strC, string strSt) getEmpInfo()
{
//code goes here
}
//Now when you call method get values with specific name as below
var empInfo= getEmpInfo();
WriteLine("Emp info as {empInfo.strFName} {empInfo.strAdd} {empInfo.strC} {empInfo.strSt}.");
另外,您可以直接在元组文字中返回其名称,如下所示
return (strFName: strFirstName, strAdd: strAddress, strCity: strC, strState: strSt);
元组是非常有用的东西,您可以轻松地替换哈希表或字典,甚至可以为单个键返回多个值。此外,您可以使用它来代替在单个位置存储多个值的List。
.NET也有一个Tuple类型(请参阅此处),但是它是一个引用类型,因此会导致性能问题,但是C#7.0带来了一个具有值类型的Tuple,该类型具有更快的性能和可变的类型。
解构
大多数时候,我们不想访问整个元组包,或者我们只需要内部值,那么我们可以使用C#7.0的解构功能,我们可以轻松地对元组进行解构并获取所需的值,下面的代码片段将消除您的怀疑
( string strFName, string strAdd, string strC, string strSt) = getEmpInfo();
Console.WriteLine($"Address: { strAdd }, Country: { strC }");
记录类型
C#支持记录类型,它只不过是属性和变量的容器,大多数时候类都充满了属性和变量,我们需要很多代码来声明它们,但是借助记录类型可以减少工作量,请参见下面的代码段
class studentInfo
{
string _strFName;
string _strMName;
string _strLName;
studentInfo(string strFN, string strMN, string strLN){
this._strFName = strFN;
this._strMName = strMN;
this._strLName = strLN;
}
public string StudentFName {get{ return this._strFName;}}
public string StudentMName {get{ return this._strMName;}}
public string StudentLName {get{ return this._strLName;}}
}
在上面的代码中,我们有一个带有属性,构造函数和变量的类,因此访问和声明变量需要编写更多代码。
为了避免这种情况,我可以在C#中使用记录类型,请参见下面的代码段
class studentInfo(string StudentFName, string StudentMName, string StudentLName);
就是这样,我们完成了!
以上代码段产生的输出与早期代码段相同。
最小化OUT
当我们想从方法返回多个值时,out参数非常流行。本质上,out参数是ref类型,可以作为参数使用,我们可以轻松使用它,但唯一的条件是out变量必须在传递之前进行初始化。见下面的片段
class SetOut
{
void AssignVal(out string strName)
{
strName = "I am from OUT";
}
static void Main()
{
string strArgu;
AssignVal(out strArgu);
// here contents of strArgu is "I am from OUT"
}
}
C#7.0减少了编写额外代码的麻烦,您可以传递参数而无需初始化它们,请参见下面的代码段
static void Main()
{
AssignVal(out string szArgu);
// here contents of szArgu is "I am from OUT"
}
您可以使用var作为参数类型来声明它们。
请注意,此处使用变量,仅在有限范围内使用,因此我们不能在方法外部使用它们
由于我们可以直接将变量定义为参数,因此C#7.0使我们可以自由地将其声明为var。因此您无需担心数据类型,请参见下面的代码段
static void Main()
{
AssignVal(out var szArgu);
// here contents of szArgu is "I am from OUT"
}
Non-“NULL”的引用类型
Null引用确实是让所有程序员的头疼的问题,它是一个百万美元的例外。如果不检查它们,就会得到运行时异常,或者如果对每个对象检查它们,那么您的代码就会变得很长,要解决此问题,C#7.0附带了不可为空的引用类型
**我认为它的语法尚未修复,但他们已经发布了以下语法
'?'是可为空的value-type和'!'用于非空引用类型
int objNullVal; //non-nullable value type
int? objNotNullVal; //nullable value type
string! objNotNullRef; //non-nullable reference type
string objNullRef; //nullable reference type
现在,运行此代码段后,请查看以下编译器效果
MyClass objNullRef; // Nullable reference type
MyClass! objNotNullRef; // Non-nullable reference type
objNullRef = null; // this is nullable, so no problem in assigning
objNotNullRef = null; // Error, as objNotNullRef is non-nullable
objNotNullRef = objNullRef; // Error, as nullable object can not be refered
WriteLine(objNotNullRef.ToString()); // Not null so can convert to tostring
WriteLine(objNullRef.ToString()); // could be null
if (objNullRef != null) { WriteLine(objNullRef.ToString); } // No error as we have already checked it
WriteLine(objNullRef!.Length); // No error
本地方法/函数
当前版本的C#中已经存在本地方法和函数(是的,我们可以使用Func和Action类型来实现它们,请参见此处Func和Action),但是本地方法仍然存在一些限制,我们不能具有以下功能
- 泛型
- out参数
- Ref
- 参数
现在,使用C#7.0,我们可以克服此问题,请参见下面的代码段
private static void Main(string[] args)
{
int local_var = 100;
int LocalFunction(int arg1)
{
return local_var * arg1;
}
Console.WriteLine(LocalFunction(100));
}
在上面的代码段中,我们将“LocalFunction”定义为位于Main Function“Main”内部的本地函数,在这里我们可以在其中使用out或ref。
很多时候我们在代码中使用文字,如果它们太长,我们可能会失去可读性,以解决此类问题,C#7.0在文字方面进行了一些改进。现在,C#允许在文字中使用“_”(下划线)以加深理解,它不会影响其值。见下面的片段
var lit1 = 478_1254_3698_44;
var lit2 = ab0Xab_bc47at_XY;
//C# also come with binary literal for bunary values
var binLit = 1100_1011_0100_1010_1001;
** 文字只是常量值(硬编码值),它可能具有预定义的含义。(C#中的文字)
C#7.0允许用户在IS语句和SWITCH语句中使用模式,因此我们可以将模式与任何数据类型匹配,模式可以是常量模式,类型模式,变量模式。以下示例代码将清除您的概念,让我们从IS模式开始
public void Method1( object obj)
{
//following null is constant pattern
if (obj is null) return;
//datatype pattern, string is datatype that we check directly
if (obj is string st)
{ //code goes here }
else
return;
}
Switch模式可以使用很多数据类型来匹配“case”子句,因此对它有很大帮助,因为它可以灵活地实现见下面的片段
class Calculate();
class Add(int a, int b, int c) : Calculate;
class Substract(int a, int b) : Calculate;
class Multiply(int a, int b, int c) : Calculate;
Calculate objCal = new Multiply(2, 3, 4);
switch (objCal)
{
case Add(int a, int b, int c):
//code goes here
break;
case Substract(int a, int b):
//code goes here
break;
case Multiply(int a, int b, int c):
//code goes here
break;
default:
//default case
break;
}
在上面的示例switch case 检查模式中,并调用“ Multiply”方法
您是否尝试过将方法/函数中的变量作为Ref返回?是的,C#7.0允许您执行此操作。感染你可以通过Ref传递一个变量,将它们作为Ref返回,并将它们存储为Ref,这不是很神奇吗。
见下面的片段
ref string getFromList(string strVal, string[] Values)
{
foreach (string val1 in Values)
{
if (strVal == val1)
return ref val1; //return location as ref not actual value
}
}
string[] values = { "a", "b", "c", "d" };
ref string strSubstitute = ref getFromList("b", values);
strSubstitute = "K"; // replaces 7 with 9 in the array
System.Write(values[1]); // it prints "K"
在上面的示例中,我们通过从方法返回Ref找到并替换了字符串。
在C#7.0中,您没看错,现在您可以直接从表达式中引发异常。见下面的片段
public string getEmpInfo( string EmpName)
{
string[] empArr = EmpName.Split(",");
return (empArr.Length > 0) ? empArr[0] : throw new Exception("Emp Info Not exist");
}
在上面的代码片段中,我们可以直接从return语句抛出异常,这不是很好吗!
以上所有功能均有望成为C#7.0的一部分,但Microsoft随Visual Studio 2015 Release 4一起发布了其中一些功能。
希望您喜欢C#7.0的这些新功能。