欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c# in depth的泛型實(shí)現(xiàn)實(shí)例代碼

 更新時(shí)間:2013年11月20日 10:03:51   作者:  
這篇文章主要介紹了c# in depth的泛型實(shí)現(xiàn)實(shí)例代碼,學(xué)C#的同學(xué)一定會(huì)用到泛型實(shí)現(xiàn)的,這里我們提供了泛型實(shí)現(xiàn)的程序代碼,大家參考使用

1.默認(rèn)值表達(dá)式
如果已經(jīng)明確了要處理的類型,也就知道了它的“默認(rèn)”值。不知道要引用的類型,就不能直接指定默認(rèn)值。不能使用null,因?yàn)樗赡懿皇且粋€(gè)引用類型,不能使用0,因?yàn)樗赡懿皇菙?shù)值類型。雖然很少需要用到默認(rèn)值,但它偶爾還是有用的。Dictionary<TKey,TValue>就是一個(gè)好的例子,它有個(gè)TryValue方法,它的作用有點(diǎn)兒像對(duì)數(shù)值類型進(jìn)行處理的TryParse方法:他用一個(gè)輸出參數(shù)來接收你打算獲取的值,用一個(gè)Boolean返回值顯示它是否成功。這意味著方法必須用TValue類型的值來填充輸出參數(shù)。請(qǐng)記住,輸出參數(shù)必須在方法正常返回之前賦值。
為了滿足這方面的要求,c#2提供了默認(rèn)值表達(dá)式。雖然c#語言規(guī)范沒有說他是一個(gè)操作符,但可以把它看做是與typeof相似的操作符,只是返回值不一樣罷了。

復(fù)制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 默認(rèn)值表達(dá)式
{
    class Program
    {
        static int CompareToDefault<T>(T value)
        where T : IComparable<T>
        {
            return value.CompareTo(default(T));
        }

        static void Main(string[] args)
        {
            Console.WriteLine(CompareToDefault("x"));
            Console.WriteLine(CompareToDefault(10));
            Console.WriteLine(CompareToDefault(0));
            Console.WriteLine(CompareToDefault(-10));
            Console.WriteLine(CompareToDefault(DateTime.MinValue));
        }
    }
}

運(yùn)行結(jié)果:

在上述代碼中,我們?yōu)榉盒头椒ㄊ褂昧?種不同的類型:string,int和DateTime. CompareToDefault方法規(guī)定只能使用實(shí)現(xiàn)了IComparable<T>接口的類型作為參數(shù),這樣才能為傳入的值調(diào)用ComparTo<T>.傳入的值要和類型的默認(rèn)值進(jìn)行比較。string是引用類型,默認(rèn)值是null—根據(jù)有關(guān)CompareTo的文檔,所有引用類型的值都要大于null,所以第一個(gè)輸出的結(jié)果是1,隨后三行和int的默認(rèn)值進(jìn)行比較,顯示int的默認(rèn)值是0.最后一行輸出0,顯示了DateTime.MinValue就是DateTime的默認(rèn)值。
如果傳遞的參數(shù)是null,上述代碼會(huì)拋出NullReferenceException異常。

2.直接比較

雖然上述代碼演示了如何進(jìn)行比較,但我們并不是總是愿意限制我們自己的類型來實(shí)現(xiàn)IComparable<T>或者它的姊妹接口IEquatable<T>,后者提供了一個(gè)強(qiáng)類型的Equals(T)方法,以彌補(bǔ)所有類型都具備的Equals(object)的不足。如果沒有接口允許我們?cè)L問一些額外的信息,那么我們能做的事情就很少了。只能調(diào)用Equals(object)。如果要比較的值時(shí)值類型,它會(huì)造成裝箱。
如果一個(gè)類型是未約束的,就可以使用==和!=操作符,但只能將該類型的值與null進(jìn)行比較。不能直接比較兩個(gè)T類型的值(會(huì)報(bào)錯(cuò),無法通過編譯),如果類型實(shí)參是一個(gè)引用類型,會(huì)進(jìn)行正常的引用比較。如果為T提供的類型實(shí)參是一個(gè)非可空值類型,與null進(jìn)行比較總是不相等(這樣一來,JIT編譯器就可以移除這個(gè)比較)。如果類型實(shí)參是可空值類型,那么就會(huì)自然而然的與類型的空值進(jìn)行比較。
如果一個(gè)類型參數(shù)被約束成值類型,就完全不能使用==和!=。如果被約束成引用類型,那么具體執(zhí)行的比較將完全取決于類型參數(shù)被約束成什么類型。如果它只是一個(gè)引用類型,那么執(zhí)行的是簡單的引用比較。如果被進(jìn)一步約束成繼承自某個(gè)重載了==和!=操作符的特定類型,就會(huì)使用重載運(yùn)算符。但要注意,假如調(diào)用者指定的類型實(shí)參恰巧也進(jìn)行了重載,那么這個(gè)重載操作符是不會(huì)使用的。

復(fù)制代碼 代碼如下:

using System.Text;
using System.Threading.Tasks;

namespace 直接比較實(shí)現(xiàn)
{
    class Program
    {
        static bool AreReferencesEqual<T>(T first, T second)
            where T:class
        {
            return first == second;
        }
        static void Main(string[] args)
        {
            string name = "Joy";
            string intro1 = "My name is "+name;
            string intro2 = "My name is "+name;
            Console.WriteLine(intro1==intro2);
            Console.WriteLine(AreReferencesEqual(intro1,intro2));
        }
    }
}

運(yùn)行結(jié)果為:


雖然string 重載了==,但在執(zhí)行的比較中是不會(huì)用這個(gè)重載的?;旧?,在說編譯AreReferencesEqual<T>時(shí),編譯器根本不知道有哪些重載可用,就好比傳入的只是object類型的參數(shù)。
并非只有操作符才有這個(gè)問題,遇到泛型類型時(shí),編譯器會(huì)在編譯未綁定時(shí)就解析好所有方法重載,而不是等到執(zhí)行時(shí),才去為每個(gè)可能的方法調(diào)用重新考慮是否存在更具體的重載。例如,Console.WriteLine(default(t));這個(gè)語句總是被解析成Console.WriteLine(object object),即使為T傳遞的類型恰好就是string,也不會(huì)調(diào)用Console.WriteLine(string value),這好比普通方法重載是發(fā)生在編譯時(shí),而不是執(zhí)行時(shí)。
需要對(duì)值進(jìn)行比較時(shí),有兩個(gè)相當(dāng)有用的類,他們是EqualityComparer<T>和Comparer<T>,兩者都位于System.Collection.Generic命名空間中。他們分別實(shí)現(xiàn)了IEqualityComparer<T>(適合對(duì)字典進(jìn)行比較和哈希處理)和IComparer<T>(適合排序)。這兩個(gè)類的Default屬性能返回一個(gè)實(shí)現(xiàn),能為特點(diǎn)的類型采取正確的比較操作。
說明:泛型比較接口  共有四個(gè)主要的泛型接口可用于比較。IComparer<T>和IComparable<T>用于排序(判斷某個(gè)值是小于、等于還是大于另一個(gè)值),而IEqualityComparer<T>和IEquatable<T>通過某種標(biāo)準(zhǔn)來比較兩個(gè)項(xiàng)的相等性,或查找某個(gè)項(xiàng)的散列(通過相等性方式匹配)
如果換一種方式來劃分這四個(gè)接口,IComparer<T>和IEqualiyComparer<T>的實(shí)例能比較兩個(gè)不同的值,而IComparer<T>和IEquatable<T>的實(shí)例則可以比較它們本身和其他值。

3.一個(gè)完整的比較實(shí)例,表示一對(duì)值

這是一個(gè)完整的實(shí)例,它實(shí)現(xiàn)了一個(gè)有用的泛型類型,也就是一個(gè)Pair<T1,T2>,用于容納兩個(gè)值,類似鍵值對(duì),但這兩個(gè)值之間沒有任何關(guān)系。
除了提供屬性來訪問值本身之外,我們還覆蓋了Equals和GetHashCode方法,從而使這個(gè)類型的實(shí)例能很好的作為字典中的鍵來使用。
 pair<T1,T2>類

復(fù)制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 表示一對(duì)值的泛型類
{
    public sealed class Pair<T1, T2> : IEquatable<Pair<T1, T2>>
    {
        private static readonly IEqualityComparer<T1> FirstComparer = EqualityComparer<T1>.Default;
        private static readonly IEqualityComparer<T2> SecondComparer = EqualityComparer<T2>.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<T1, T2> 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<T1,T2>);
        }
        public override int GetHashCode()
        {
            return FirstComparer.GetHashCode(first) * 37 + SecondComparer.GetHashCode(second);
        }
    }
}

Pair<T1,T2>輔助類

復(fù)制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 表示一對(duì)值的泛型類
{
    public static class Pair
    {
        public static Pair<T1, T2> Of<T1, T2>(T1 first, T2 second)
        {
            return new Pair<T1, T2>(first,second);
        }
    }
}

主體方法

復(fù)制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 表示一對(duì)值的泛型類
{
    class Program
    {
        static void Main(string[] args)
        {
            Pair<string, string> pair1 = new Pair<string, string>("hello","world");
            Pair<string, string> pair2 = new Pair<string, string>("hello", "world");
            Pair<int, string> pair3 = new Pair<int, string>(1,"hello world");
            bool c = pair1.Equals(pair2);
            bool d = pair2.Equals(pair3);
            System.Console.WriteLine(c);
            System.Console.WriteLine(d);
            System.Console.WriteLine(pair2.GetHashCode());

        }
    }
}

運(yùn)行結(jié)果

相關(guān)文章

  • Unity實(shí)現(xiàn)人物平滑轉(zhuǎn)身

    Unity實(shí)現(xiàn)人物平滑轉(zhuǎn)身

    這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)人物平滑轉(zhuǎn)身,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • DataGridView控件顯示行號(hào)的正確代碼及分析

    DataGridView控件顯示行號(hào)的正確代碼及分析

    今天要用到DataGridView,想給它動(dòng)態(tài)的顯示行號(hào)。于是在網(wǎng)上找了一下解決方法。結(jié)果發(fā)現(xiàn)了不少問題。然而就是這么一段有錯(cuò)的代碼,幾乎充斥著整個(gè)互聯(lián)網(wǎng),千篇一律的COPY,沒有一個(gè)人糾正
    2013-08-08
  • Unity3D實(shí)現(xiàn)物體排成弧行

    Unity3D實(shí)現(xiàn)物體排成弧行

    這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)物體排成弧行,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • C# 觀察者模式實(shí)例介紹

    C# 觀察者模式實(shí)例介紹

    一個(gè)簡單的例子,比如說貓叫,老鼠跑,主人被驚醒,在不知道觀察者模式之前,我們的代碼可能是這樣的
    2012-10-10
  • 基于C#實(shí)現(xiàn)哈夫曼樹算法

    基于C#實(shí)現(xiàn)哈夫曼樹算法

    哈夫曼樹又稱最優(yōu)二叉樹,也就是帶權(quán)路徑最短的樹,對(duì)于哈夫曼樹,我想大家對(duì)它是非常的熟悉,使用下面我們就來學(xué)習(xí)一下如何通過C#實(shí)現(xiàn)哈夫曼樹算法吧
    2023-11-11
  • C#實(shí)現(xiàn)屬于自己的QQ截圖工具

    C#實(shí)現(xiàn)屬于自己的QQ截圖工具

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)屬于自己的QQ截圖工具的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-04-04
  • C#中WinForm程序退出方法技巧總結(jié)

    C#中WinForm程序退出方法技巧總結(jié)

    這篇文章主要介紹了C#中WinForm程序退出方法,實(shí)例總結(jié)了技巧退出WinForm程序窗口的各種常用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-12-12
  • C#中通過API實(shí)現(xiàn)的打印類 實(shí)例代碼

    C#中通過API實(shí)現(xiàn)的打印類 實(shí)例代碼

    這篇文章介紹了,C#中通過API實(shí)現(xiàn)的打印類 實(shí)例代碼,有需要的朋友可以參考一下
    2013-08-08
  • C# 設(shè)計(jì)模式系列教程-原型模式

    C# 設(shè)計(jì)模式系列教程-原型模式

    原型模式隱藏了對(duì)象的創(chuàng)建細(xì)節(jié),對(duì)有些初始化需要占用很多資源的類來說,對(duì)性能也有很大提高。
    2016-06-06
  • 在.net應(yīng)用程序中運(yùn)行其它EXE文件的方法

    在.net應(yīng)用程序中運(yùn)行其它EXE文件的方法

    這篇文章主要介紹了在.net應(yīng)用程序中運(yùn)行其它EXE文件的方法,涉及C#進(jìn)程操作的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05

最新評(píng)論