针对不同版本(C#1~4)的特性优缺点举例说明:
C#1:只读属性、弱类型集合、弱类型的比较功能、不支持委托排序、简易查询集合
using System.Collections;
using System.Collections.Generic;
using UnityEngine;//Unity引擎的一个命名空间
public class MyTest
{
private static void Init()
{
'''//C#1:弱类型集合ArrayList,存储的是object,Add时会进行隐式转换为object'''
ArrayList arrayList = new ArrayList();
arrayList.Add(new Food("apple", 2));
arrayList.Add(new Food("banner", 1));
arrayList.Add(new Food("orange", 5));
arrayList.Add("this is a string");
arrayList.Add(100);
arrayList.Add(true);
'''//并且需要清楚取出的是具体什么类型才能转'''
Food f1 = (Food)arrayList[1];'''//取出时需要将object->Food强转'''
int i4 = (int)arrayList[3];
arrayList.Sort(new FoodNameComparer());'''//利用比较器进行排序原始arrayList数据(真正的发生了改变)'''
'''//C#1:简易方式查询集合并打印输出(高耦合)三个操作:遍历、if测试、打印输出依赖性强,插入复杂操作困难'''
'''//1.迭代器方式遍历arrayList'''
foreach (Food food in arrayList)
{
'''//2.测试'''
if (food.Price > 1)
{
'''//3.打印输出'''
Debug.Log(food);'''//Debug.Log是UnityEngine(Unity引擎特有的打印方法)可替换为Console.Write() 或 print'''
}
}
}
}
'''//C#1:比较器'''
class FoodNameComparer : IComparer
{
public int Compare(object x, object y)
{
'''//必须先强转'''
Food first = (Food)x;
Food second = (Food)y;
return first.Name.CompareTo(second.Name);'''//升序排序'''
}
}
public class Food
{
'''//C#1:只读属性'''
private string name;
public string Name { get { return name; } }
private decimal price;
public decimal Price { get { return price; } }
public Food(string name, decimal price)
{
this.name = name;
this.price = price;
}
public override string ToString()
{
return string.Format("{0}:{1}", name, price);
}
}
C#2:私有属性赋值方法、强类型集合、强类型的比较功能、委托比较、匿名方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine; '''//Unity引擎的一个命名空间'''
using System.Linq; '''//C#3的Linq'''
public class MyTest
{
private static void Init()
{
'''//C#2:强类型集合 利用泛型 约束成员类型为Food'''
'''//优点:无需隐式转换,存储固定类型成员'''
List<Food> arrayList = new List<Food>();
arrayList.Add(new Food("apple", 2));
arrayList.Add(new Food("banner", 1));
arrayList.Add(new Food("orange", 5));
'''//arrayList.Add("this is a string");//尝试传入非Food类型,编译期报错'''
Food f = arrayList[0];
'''//1.C#2:使用比较器进行排序'''
//arrayList.Sort(new FoodNameComparer());
'''//2.C#2: 使用委托'''
arrayList.Sort(delegate (Food x, Food y)
{
return x.Name.CompareTo(y.Name);
});
'''C#1简易做法:查询集合打印输出'''
'''//foreach (Food food in arrayList)'''
'''//{'''
'''// if (food.Price > 1)'''
'''// {'''
'''// Debug.Log(food);'''
'''// }'''
'''//}'''
'''//*********************************************'''
'''拆分:先进行遍历测试过滤,再进行遍历打印'''
'''//System.Predicate<Food> test = delegate (Food food) { return food.Price > 1; };'''
'''FindAll和ForEach是List的方法
'''其中FindAll会遍历集合,并且使用传入的委托进行测试(相当于测试器)只有测试通过的元素才会保留下来'''
'''ForEach几乎一样,遍历集合使用委托打印'''
'''//List<Food> tempList = arrayList.FindAll(test);'''
'''//System.Action<Food> print = Debug.Log;//方法组转换(Action<Food>无返回值有参委托)'''
'''//tempList.ForEach(print);'''
'''//*********************************************'''
'''//*********************************************分隔符,上面分隔符之间的代码一样,只是多了一个排序操作,这样能更加清晰为什么要这样拆分'''
'''//假设在第一次过滤后,我想插入新的过滤方式(或者其他操作)'''
'''//拆分:先进行遍历测试过滤,再进行遍历打印'''
System.Predicate<Food> test = delegate (Food food) { return food.Price > 1; };
List<Food> tempList = arrayList.FindAll(test);
'''//插入新操作:按Name升序排序'''
tempList = tempList.OrderBy(o => o.Name).ToList();
System.Action<Food> print = Debug.Log;'''//方法组转换(Action<Food>无返回值有参委托)'''
tempList.ForEach(print);
'''//*********************************************'''
}
}
'''//C#2:比较器'''
class FoodNameComparer : IComparer<Food>
{
public int Compare(Food x, Food y)
{
return x.Name.CompareTo(y.Name);'''//升序排序'''
}
}
public class Food
{
'''//C#2:支持私有属性赋值方法private set{}'''
private string name;
public string Name { get { return name; } private set { name = value; } }
private decimal price;
public decimal Price { get { return price; } private set { price = value; } }
public Food(string name, decimal price)
{
this.name = name;
this.price = price;
}
public override string ToString()
{
return string.Format("{0}:{1}", name, price);
}
}
C#3:表达式、扩展方法、允许列表保持未排序状态、可空(null)值类型
using System.Collections;
using System.Collections.Generic;
using System.Linq;'''//C#3的Linq'''
using UnityEngine;'''//Unity引擎的一个命名空间'''
public class MyTest
{
public static void Init()
{
'''//C#3: 增强的集合和对象初始化'''
List<Food> arrayList = new List<Food>() {
new Food("apple", 2),
new Food("banner", null)
};
'''//C#3: 使用Lambda表达式进行排序(在委托基础上更加简化)'''
'''//arrayList.Sort((x, y) => x.Name.CompareTo(y.Name));'''
'''//C#3:利用Linq语句排序,注意这种排序方法不会对原始数据进行修改 [PS:需引入新的命名空间:System.Linq]'''
foreach (Food food in arrayList.OrderByDescending(p => p.Name))
{
Debug.Log("倒序排序后结果:" + food);
}
foreach (Food food in arrayList)
{
Debug.Log("原始数据:" + food);
}
'''//使用ExtentFun静态类内的Food类扩展方法Test1'''
Food f = arrayList[0];
f.Test1("i am food!");
}
}
'''//扩展方法实现类'''
public static class ExtentFun
{
'''//对Food进行扩展一个方法名为Test1'''
public static void Test1(this Food food, string descript)
{
Debug.Log(string.Format("{0}:{1}", food.Name, descript));
}
}
public class Food
{
'''//C#3:支持自动实现的属性,只需一个属性字段,确保了一致性(也就是没有name,price了)'''
public string Name { get; set; }
'''//C#3:可空(null)的值类型 decimal? (例如int? float? double? 都可行)'''
public decimal? Price { get; set; }
public Food(string name, decimal? price)
{
Name = name;
Price = price;
}
public override string ToString()
{
return string.Format("{0}:{1}", Name, Price);
}
}
C#4:命名实参、参数默认值
using System.Collections;
using System.Collections.Generic;
using UnityEngine;'''//Unity引擎的一个命名空间'''
public class MyTest
{
private static void Init()
{
List<Food> arrayList = new List<Food>() {
'''//C#4: 命名实参'''
new Food(name : "apple", price : 2),
'''//C#4: 参数默认值用法'''
new Food("banner") '''//此时,不对price形参进行传参赋值,构造方法会采用decimal.MinValue赋值给price形参'''
};
Food f = arrayList[0];
'''//利用命名实参(更加清晰地认识自己传参,以及选择性传参譬如一个方法有10多个参数,你可以用命名实参来只对特定的几个参数进行赋值,但必须其他参数要有默认值)'''
f.Fun1(arg1:"1");'''//仅对arg1进行赋值,其他参数不进行赋值采用默认值'''
}
}
public class Food
{
public string Name { get; set; }
public decimal Price { get; set; }
'''//C#4: 方法的参数默认值'''
public Food(string name = "", decimal price = decimal.MinValue)
{
Name = name;
Price = price;
}
'''//有默认值的参数必须放于所有未带有默认值的参数之后进行赋值!(如下代码会编译出错)'''
'''//public void Fun1(string arg1 = "", string arg2, int arg3 , bool arg4)'''
'''//{'''
'''//}'''
public void Fun1(string arg1 = "", string arg2 = "", int arg3 = int.MinValue, bool arg4 = false)
{
}
}
简化COM互操作、动态类型【C#4】
下面创建的是控制台程序:实现将集合存储入Excel表格保存
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Excel;//需引入Microsoft.Office.Interop.Excel
//引入方法:工具->NuGet 包管理器 -> 管理解决方案的NuGet程序包 -> 查找Microsoft.Office.Interop.Excel 下载安装 重启VS
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var app = new Application { Visible = false };
Workbook workbook = app.Workbooks.Add();
//ActiveSheet是dynamic类型(运行时才会转化为Worksheet类型)
Worksheet worksheet = app.ActiveSheet;
int row = 1;
foreach (var product in new List<Product>() {
new Product("a","100"),
new Product("e","1020"),
new Product("d","1030"),
new Product("c","1040"),
new Product("b","1050")
}.Where(p=>p.Price != null)){
worksheet.Cells[row, 1].Value = product.Name;
worksheet.Cells[row, 2].Value = product.Price;
row++;
}
//FileName相对路径是电脑/文档[利用了命名参数简化赋值]
workbook.SaveAs(Filename: @"E:\UnityProject\LearnCSharp\CSharpLearn\RuntimeCSharpLearn\demo.xls", FileFormat: XlFileFormat.xlWorkbookNormal);
app.Application.Quit();
Console.Write("Over!");
}
}
public class Product
{
public string Name { get; set; }
public string Price { get; set; }
public Product(string n, string p)
{
Name = n;
Price = p;
}
}
}