1.List排序
class Item:IComparable<Item>
{
public int money;
public Item(int money)
{
this.money = money;
}
public int CompareTo(Item other)
{
//返回值的含义
//小于0
//放在传入对象的前面
//等于0
//保持当前位置不变
//大于0
//放在传入对象的后面
//可以简单理解 传入对象的位置 就是0
//如果你的返回为负数 就放在它的左边 也就是前面
//如果你的返回为正数 就放在它的右边 也就是后面
if (this.money > other.money)
{
return 1;
}
else
{
return -1;
}
}
}
class ShopItem
{
public int id;
public ShopItem(int id)
{
this.id = id;
}
}
1.List自带排序方法
List<int> list = new List<int>();
list.Add(3);
list.Add(2);
list.Add(6);
list.Add(1);
list.Add(4);
list.Add(5);
for (int i = 0; i < list.Count; i++)
{
Console.Write(list[i]+" ");
}
Console.WriteLine();
//list提供了排序方法
list.Sort();
for (int i = 0; i < list.Count; i++)
{
Console.Write(list[i] + " ");
}
Console.WriteLine();
//ArrayList中也有Sort排序方法
2.自定义类的排序
List<Item> itemList = new List<Item>();
itemList.Add(new Item(45));
itemList.Add(new Item(10));
itemList.Add(new Item(99));
itemList.Add(new Item(24));
itemList.Add(new Item(100));
itemList.Add(new Item(12));
//排序方法
itemList.Sort();
for (int i = 0; i < itemList.Count; i++)
{
Console.WriteLine(itemList[i].money);
}
3.通过委托函数进行排序
List<ShopItem> shopItems = new List<ShopItem>();
shopItems.Add(new ShopItem(2));
shopItems.Add(new ShopItem(1));
shopItems.Add(new ShopItem(4));
shopItems.Add(new ShopItem(3));
shopItems.Add(new ShopItem(6));
shopItems.Add(new ShopItem(5));
//shopItems.Sort(SortShopItem);
//shopItems.Sort(delegate (ShopItem a, ShopItem b)
//{
// if (a.id > b.id)
// {
// return 1;
// }
// else
// {
// return -1;
// }
//});
//lambda表达式 配合 三目运算符的 完美表现
shopItems.Sort((ShopItem a, ShopItem b) =>{return a.id > b.id ? 1 : -1;});
for (int i = 0; i < shopItems.Count; i++)
{
Console.WriteLine(shopItems[i].id);
}
static int SortShopItem(ShopItem a, ShopItem b)
{
//传入的两个对象 为列表中的两个对象
//进行两两比较 用左边的和右边的条件 比较
//返回值规则 和之前一样 0作标准 负数在左(前) 正数在后(后)
if (a.id > b.id)
{
return 1;
}
else
{
return -1;
}
}
4.总结
系统自带的变量(int, float, double.....) 一般都可以直接Sort
自定义类SOrt有两种方式
1.继承接口 IComparable
2.在Sort中传入委托函数
2.协变逆变
1.什么是协变逆变
协变:
和谐的变化,自然的变化
因为 里氏替换原则 父类可以装子类
所以 子类变父类
比如 string 变成 object
感受是和谐的
逆变:
逆常规的变化,不正常的变化
因为 里氏替换原则 父类可以装子类 但是子类不能装父类
所以 父类变子类
比如 object 变成 string
感受是不和谐的
协变和逆变是用来修饰泛型的
协变:out
逆变:in
用于在泛型中 修饰 泛型字母的
只有泛型接口和泛型委托能使用
2.作用
1.返回值 和 参数
//用out修饰的泛型 只能作为返回值
delegate T TestOut<out T>();
//用in修饰的泛型 只能作为参数
delegate void TestIn<in T>(T t);
interface Test<out T>
{
T TestFun();
}
2.结合里氏替换原则理解
class Father
{
}
class Son : Father
{
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("协变逆变");
#region 作用(结合里氏替换原则理解)
//协变 父类总是能被子类替换
//看起来 就是 Son-->father
TestOut<Son> os = () =>
{
return new Son();
};
TestOut<Father> of = os;
Father f = of();//实际上 返回的 是os里面装的函数 返回的是Son
//逆变 父类总是能被子类替换
TestIn<Father> iF = (value) =>
{
};
TestIn<Son> iS = iF;
iS(new Son());//实际上 调用的是 iF
#endregion
}
}
3.总结
协变 out
逆变 in
用来修饰 泛型替代符的 只能修饰接口和委托中的泛型
作用两点
1.out修饰的泛型类型 只能作为返回值类型 in修饰的泛型类型 只能作为 参数类型
2.遵循里氏替换原则的 用out和in修饰的 泛型委托 可以相互装载(有父子关系的泛型)
协变 父类泛型委托装子类泛型委托 逆变 子类泛型委托装父类泛型委托