c# 判断 泛型t 类型_C# 中级泛型-泛型比较与类型推断

泛型方法类型推断

有以下代码:

static List MakeList(T first,T second);

{

......

}

List list = MakeList("a1","b1");

可以简写成:

List list = MakeList("a1","b1");

在这里就使用到了泛型类型推断,但是类型推断只适用于泛型方法。

默认值表达式

在一个泛型类当中,你如果要知道该类型参数的默认值,不能使用null,因为类型参数可能被约束为值类型,你也不能使用0,因为也有可能被约束为引用类型。在C#2当中提供了默认值表达式default(T),就可以返回类型实参的默认值。

static int CompareToDefault(T value) where T : IComparable

{

return value.CompareTo(default(T));

}

Console.WriteLine(ComparaToDefault("x")); //1

Console.WriteLine(ComparaToDefault(10)); //1

Console.WriteLine(ComparaToDefault(0)); //0

Console.WriteLine(ComparaToDefault(-10)); //-1

Console.WriteLine(ComparaToDefault(DateTime.MinValue)); //0

由CompareTo文档指出,所有引用类型的值都大于null,所以返回1,CompareTo,如果比较的值比自己大则为1,相等则为0,小于则为-1。

不过如果传入的是null,以上代码会如预期的抛出NullReferenceException异常,我们可以使用IComparer。

泛型比较

如果一个类型参数是未被约束的,那么只能在泛型类直线中对该类型的值与null进行比较的时候才可以使用!=、==操作符。

如果类型参数被约束为值类型,那么就完全不能使用!=、==操作符。

如果他只是一个引用类型,则只能进行简单的引用比较,可以使用!=、==操作符。

如果他被进一步约束成继承自某个重载了的!=、==操作符的特定类型(即转换类型约束),就会使用重载操作符。

如果调用者指定的类型实参恰巧也进行了重载,那么这个重载操作符是不会使用的

static bool AreReferenceEqual(T first,T second) where T : class

{

return first == second;

}

string name = "Jon";

string intro1 = "Hello " + name;

string intro1 = "Hello " + name;

Console.WriteLine(intro1 == intro2);

Console.WriteLine(AreReferenceEqual(intro1,intro2));

在这里,第一行输出为True,是因为这里使用的是string重载过的比较操作符,用于比较两个字符串是否相等。

而第二行输出为False,是因为在编译AreReferenceEqual的时候,编译器根本不知道有哪些重载可用,因为我们约束的是class,所以相当于传入的类型实参是object。

不仅仅是操作符的时候,编译器会在编译未绑定泛型类型的时候就解析好所有方法重载,而不是等到执行时。

在对值进行比较的时,有两个相当有用的类,分别是EqualityComparer和Comparer,他们分别实现了IEqulalityComparer和IComparaer这两个接口。这两个类分别有一个Default的属性能够返回一个实现,能为特定的特定的类型才去正确的比较操作。

IComparaer和IComparable用于排序,判断某个值是小于、等于、还是大于另一个值。

IEqualityComparer和IEquatable则是通过某种标准来比较两个项的相等型,或者查找某个项的散列值。

IComparaer和IEqualityComparer的实例能够比较两个不同的值。

IComparable和IEquatable只能比较它们本身和其他的值。

实现类似元组的泛型对值

public sealed class Pair : IEquatable> //这里我们实现了IEquatable,提供了一个强类型的API(Equals方法),可以避免不必要的运行时类型检查。

{

// 生成一个默认的比较器,可以自动处理null值的情况

private static readonly IEqualityComparer FirstComparer = EqualityComparer.Default;

private static readonly IEqualityComparer SecondComparer = EqualityComparer.Default;

private readonly T1 first;

private readonly T2 second;

public Pair(T1 first, T2 second)

{

this.first = first;

this.second = second;

}

public T1 First { get { return first; } }

public T2 Second { get { return second; } }

public bool Equals(Pair other)

{

return other != null && FirstComparer.Equals(this.First, other.first) &&

SecondComparer.Equals(this.Second, other.Second);

}

public override bool Equals(object obj)

{

return Equals(obj as Pair);

}

public override int GetHashCode()

{

return FirstComparer.GetHashCode(first) * 37 + SecondComparer.GetHashCode(second);

}

// public static Pair Of(T1 first,T2 second)

public static Pair Of(T1 first,T2 second)

{

return new Pair(first, second);

}

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值