常用集合和泛型
1 int[]是引用类型还是值类型
2 数组之间如何进行转换
3 解释泛型的基本原理
4 什么是泛型的主要约束和次要约束
数组类型是一族类型,它们都继承自System.Array,而System.Array又继承自System.Object。所有数组的类型都是引用类型。
引用类型的数组和值类型的数组的内存分配:
数组类型在符合条件的情况下可以进行隐式地转换,条件包括:数组维数必须相同;目标项目类型和源项目类型必须存在隐式或者显示转换关系;原数组项目类型不是值类型。
数组类型可通过Array.ConvertAll方法进行内容转换,该方法需要使用者提供一个转换算法,以委托或者方法的形式传入Array.ConvertAll方法中。
//编译成功 string[] sz = {"a","a","a"}; object[] oz = sz; //编译失败,值类型项目的数组不能被转换 int[] sz = {1, 2, 3}; object[] oz = sz; //编译失败,两者维数不同 string[,] sz = {{"a","b"},{"a","c"}; object[] oz = sz;
数组内容转换示例:
class ArrayConvert { static void Main(string[] args) { String[] times={"2018-1-1", "2018-1-2", "2018-1-3"}; //使用不同的方法转换 DateTime[] result1 = OneByOne(times); DateTime[] result2 = ConvertAll(times); //结果是相同的 foreach (DateTime item in result1) Console.WriteLine(item.ToString("yyyy-MM-dd")); foreach (DateTime item2 in result2) Console.WriteLine(item2.ToString("yyyy-MM-dd")); Console.Read(); } //逐个手动转换 private static DateTime[] OneByOne(String[] times) { List<DateTime> result = new List<DateTime>(); foreach (String item in times) { result.Add(DateTime.Parse(item)); } return result.ToArray(); } //使用Array.ConertAll方法 private static DateTime[] ConvertAll(String[] times) { return Array.ConvertAll(times, new Converter<String, DateTime> (ArrayConvert.DateTimeToString)); } private static DateTime DateTimeToString(String time) { return DateTime.Parse(time); } }
输出:
2018-01-01
2018-01-02
2018-01-03
2018-01-01
2018-01-02
2018-01-03
泛型允许程序员定义更通用的类型和算法,并且在具体使用时在生成具体的封闭类型。所有代泛型参数的类型都是一个开放式类型,它不能被实例化,但具备所有封闭类型的其他特性,本质上,它和封闭类没有区别。在.NET中,泛型的另外一个重要作用是避免容器操作中的装箱拆箱。
泛型示例:
class MainClass { static void Main(string[] args) { //从开放类型到封闭类型 GenericClass<String> gc = new GenericClass<String>("我是泛型"); Console.WriteLine(gc); Console.Read(); } } //一个简单的泛型类 public class GenericClass<T> { T my; public GenericClass(T t) { my = t; } public override string ToString() { return my.ToString(); } }
微软建议所有的泛型参数名称都以T开头,就像接口都以I开头一样,是一种编码的通用规范。
每个泛型参数可以有至多一个主要约束,泛型的主要约束是指指定泛型参数必须是或者继承自某个引用类型,有两个特殊的主要约束:class和struct,分别代表泛型参数引用类型和值类型。
每个泛型参数可以有无数个次要约束,次要约束和主要约束的语法基本相同,但它规定的是某个泛型参数必须实现所有次要约束指定的接口。
泛型主要约束示例:
public class ClassT1<T> where T : Exception { private T myException; public ClassT1(T t) { myException = t; } public override string ToString() { //主要约束保证了myException拥有source成员 return myException.Source; } } public class ClassT2<T> where T : class { private T myT; public void Clear() { //T是引用类型,可以置null myT = null; } } public class ClassT3<T> where T : struct { private T myT; public override string ToString() { //T是值类型,不会发生NullReferenceException异常 return myT.ToString(); } }
转载请注明出处: