using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace ConsoleApplication2
{
    public class SortAlgorithm
    {
        // 插入排序
        public static void InsertSort<T, C>(T[] array, C comparer)               ---------------(1)
             where C : IComparer<T>
        {
            for (int i = 1; i <= array.Length - 1; i++)
            {
                //Console.Write("{0}: ", i);
                int j = i;
                while (j >= 1 && comparer.Compare(array[j], array[j - 1]) < 0)
                {
                    swap(ref array[j], ref array[j - 1]);
                    j--;
                }
                //Console.WriteLine();
                //AlgorithmHelper.PrintArray(array);
            }
        }        // 交换数组array中第i个元素和第j个元素
        private static void swap<T>(ref T x, ref T y)
        {
            // Console.Write("{0}<-->{1} ", x, y);
            T temp = x;
            x = y;
            y = temp;
        }
    }    public class AlgorithmHelper
    {
        // 打印数组内容
        public static void PrintArray<T>(T[] array)
        {
            Console.Write("   Array:");
            foreach (T item in array)
            {
                Console.Write(" {0}", item);
            }
            Console.WriteLine();
        }
    }    // 获得Comparer,进行比较
    public class ComparerFactory
    {
        public static IComparer<int> GetIntComparer()      --------------------------(2)???
        {
            return new IntComparer();
        }        public class IntComparer : IComparer<int>
        {
            public int Compare(int x, int y)
            {
                return x.CompareTo(y);
            }
        }
    }
    public class client
    {
        static void Main(string[] args)
        {
            int[] array = { 42, 20, 17, 13, 28, 14, 23, 15 };
            //int[] array = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
            AlgorithmHelper.PrintArray(array);            SortAlgorithm.InsertSort
                (array, ComparerFactory.GetIntComparer());
        }
    }
}大家好,这段程序来自一位博主的排序算法,运用泛型实现的,不明白(2)中泛型表示直接把类型int加到IComparer<>中,为啥不和(1)中一样,直接用IComparer<T>方式表示。运行了一下,改成(1)一样编译不过的泛型的调用我理解应该都像(1)一样么。。如果用(2)的方式还是泛型方式么?实在想不通

解决方案 »

  1.   

    任何概念都得落地,不落地就是理论骗子。就好像你声明变量并且用来引用一个对象实例,那么对象实例必定有其真实的实例化对象类型,不管你这个变量声明为什么兼容类型(包括接口类型),最终这个变量当时所引用的对象实例都有一个最终真实的对象类型。GetIntComparer()  方法是用来返回一个真实的结果的,不是用来声明一个模板的,所以必须落地。那么 GetIntComparer() 方法越是实实在在的就越有可操作性。如果你说什么方法的return 都是声明为 object 类型(或者 dynamic),那么这不就成了弱类型糊弄编译器、糊弄编程检查者自己了嘛。做任何事情既要懂得抽象有要懂得具体,那种只知道抽象的人是行动”不落地“的骗子,那种只知道拼凑技术的人是缺乏设计概念的抄袭者。程序要经得起良好的编译器的检查,要经得起好的工程方法的测试,任何 T 必定是有具体的(例如)int 来对应,不会只玩儿标题党的。
      

  2.   

    一组设计层次,只是在它自己的范畴里边来比较,不可能全都设计成为空中楼阁。比如说 ComparerFactory 这个层次也许不应该针对 int 来设计,那么它必定要有一组 int、double、Datetime、String 甚至多种自定义常见类型的扩展实现层次。你只能说它内部在某个层次的抽象不合适,你不能说任何东西都应该抽象。如果一味追求万能的抽象,那么其实就”万万不能“地什么也做不出来的标题党了。
      

  3.   

    这段代码应该是抄自 MSDN 的范例代码
    要排序就要比较成员的大小,而为了综合不同类型比较大小的方法的不一致,C# 定义了一个 IComparer 接口。只要类型实现了这个接口,那么就会有相应的 Compare 方法可用。
    因此代码中有  where C : IComparer<T> C 是一个实现了 IComparer 接口的类型 T
    就相当于有  T.Compare 方法可用
    但是直接这样写是不可以的,因为 T 只是个代词,必须代之以真实的类型
    这就是有 IComparer<int> GetIntComparer() 的原因,因为在这段代码中 T 的真实类型是 int
    如果是自定义类型 MyClass
    就应写作 IComparer<MyClass> GetIntComparer()而 IComparer<int> GetIntComparer() 显然只是为了教学儿写的,因为C# 对 int 已经实现了 IComparer 接口当然,你还是需要对 MyClass 去实现 IComparer 接口
      

  4.   

     
      public class ComparerFactory<T> where T : IComparable
        {
            public static IComparer<T> GetIntComparer()
            {
                return new Comparer<T>();
            }
        }
        public class Comparer<T> : IComparer<T> where T : IComparable
        {
            public int Compare(T x, T y)
            {
                return x.CompareTo(y);
            }
        }我像这样改了一下,好像就可以了
      

  5.   

    非常感谢大家帮忙回复~~~,抱歉我表述的不是很准确,ltt102858的回复应该是我问题的初衷,
    但还是觉得很晕感觉自己概念不清,想继续明确一下。。
    1,原程序中:直接将int类型在此实例化,下面两个类或者对应的(2)还和泛型有关系么?应该已经没关系了是吧。
    public class ComparerFactory
         {
             public static IComparer<int> GetIntComparer()      --------------------------(2)
            {
                 return new IntComparer();
             }         public class IntComparer : IComparer<int>
             {
                 public int Compare(int x, int y)
                 {
                     return x.CompareTo(y);
                 }
             }
    2,对于ltt102858的回复,where T : IComparable变成where T : IComparable<T>,为什么就不行呢?  public class ComparerFactory<T> where T : IComparable
        {
            public static IComparer<T> GetIntComparer()
            {
                return new Comparer<T>();
            }
        }
        public class Comparer<T> : IComparer<T> where T : IComparable
        {
            public int Compare(T x, T y)
            {
                return x.CompareTo(y);
            }
        }
     3,上面这个不用泛型类,用泛型方法实现可以么?小白自己搞了半天好像不行,大牛帮看看~~ 谢谢~
      

  6.   


    你好啊,请问下,这个泛型约束改成where T : IComparable<T>怎么表达呢?
      

  7.   


    你好啊,请问下,这个泛型约束改成where T : IComparable<T>怎么表达呢?T是一个类型,给T加约束,不能让T这个类型继承于一个泛型接口吧,所以只能写T:IComparable。
      

  8.   

    这个就技术层面论,前面已经说了我得告诉你的是,这个其实不是技术层面上的事情,这个是抽象层面的问题。比如加法
    1+1=2 没错把
    1杯酒+1杯酒 等于什么?2杯酒么?
    1个男人+1个女人 等于什么泛型这种问题,就我个人技术储备来说,他来源与C++的stl,也就是算法和模板。来源与通用和特化所以并非你的(1)和(2),他其实表达的是通用层面的“加法”和特化层面的“加法”你如果能想明白 IAdd<int>那是1+1,而 IAdd<沙子>那是一堆沙+一堆沙还是等于一堆沙的话,你的问题就解决了
      

  9.   

    其实很多这种东西都是一样的,默认上object的Equals比较的是对象的引用。但是你能写 “abc".Equals("abc"), 为啥他可以这样,而且你能得到你想要的结果??原因他被特化到string类型上了