2011-09-27 73 views
1

我创建了一个方法来组织不知道类型的通用列表,它将对它的int或decimal进行排序。如何在不知道类型的情况下实例化通用列表

然而,从文本框检索值的代码使用列表

我试图将其转换为列表,但它不工作。 我想要这个代码工作,如果他们在文本框中键入整数或小数或字符串。

这是一个面试问题,他们不愿使用的排序方法的一部分,并且输入应接收例如INTS或小数

private void btnSort_Click(object sender, EventArgs e) 
     { 
      List<int> list = new List<int>(); 
      list.Add(int.Parse(i1.Text)); 
      list.Add(int.Parse(i2.Text)); 
      list.Add(int.Parse(i3.Text)); 
      list.Add(int.Parse(i4.Text)); 
      list.Add(int.Parse(i5.Text)); 
      Sort(list); 
      StringBuilder sb = new StringBuilder(); 
      foreach (int t in list) 
      { 
       sb.Append(t.ToString()); 
       sb.AppendLine(); 
      } 
      result.Text = sb.ToString(); 
     } 


     private void Sort<T>(List<T> list) 
     { 
      bool madeChanges; 
      int itemCount = list.Count; 
      do 
      { 
       madeChanges = false; 
       itemCount--; 
       for (int i = 0; i < itemCount; i++) 
       { 
        int result = Comparer<T>.Default.Compare(list[i], list[i + 1]); 

        if (result > 0) 
        { 
         Swap(list, i, i + 1); 
         madeChanges = true; 
        } 
       } 
      } while (madeChanges); 
     } 


     public List<T> Swap<T>(List<T> list, 
       int firstIndex, 
       int secondIndex) 
     { 
      T temp = list[firstIndex]; 
      list[firstIndex] = list[secondIndex]; 
      list[secondIndex] = temp; 

      return list; 
     } 

我想这样的事情:但给人错误 错误1无法找到类型或命名空间名称'T'(您是否缺少using指令或程序集引用?)c:\ users \ luis.simbios \ documents \ visual studio 2010 \ Projects \ InterViewPreparation1 \ InterViewPreparation1 \ Generics \ GenericsSorting1.cs 22 18 InterViewPreparation1

List list = new List(); list.Add(i1.Text); list.Add(i2.Text); 分类(列表);

+7

为什么祈祷告诉你不是使用'List .Sort'? – jason

+0

+1给Jason。这里是文档:http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx –

+3

,因为它是一个面试问题,他们要求不要使用排序方法。 –

回答

2

因为其采访问题,他们要求不要使用 排序方法。

在这种情况下,您可以添加通用约束IComparable<T>,然后使用CompareTo()方法:

private void Sort<T>(List<T> list) where T : IComparable<T> 
{ 
    //... 
} 

编辑:

你将不得不编写自定义代码,以确定是否输入是字符串,int或小数,即使用TryParse(..) - 这将是非常脆弱的。一旦你知道的类型(单程或其他),你可以使用MakeGenericType()Activator.CreateInstance()在运行时创建List<T>对象,然后使用MakeGenericMethod()打电话给你的泛型方法:

Type type = typeof(string); 
IList list = (IList) Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); 
//add items to list here 

var p = new Program(); 
MethodInfo method = typeof(Program).GetMethod("Sort"); 
MethodInfo genericMethod = method.MakeGenericMethod(new Type[] { type }); 
genericMethod.Invoke(p, new [] {list}); 

我敢肯定这是不是面试问题打算要求什么。

+0

我明白,但我的问题是如何实例化列表,所以我不必定义列表将会是整数或小数。这甚至有可能吗?列表 list = new List (); list.Add(i1.Text); –

+1

@Luis:你想*检测*输入类型是什么?你至少在运行时需要知道类型是什么,在这里使用泛型 – BrokenGlass

+0

是的,那是我的想法,我不知道这是不可能的。但至少我所做的排序方法是通用的。 –

1

首先,正如Jason所指出的那样,让平台为您做好工作 - 打电话给.Sort。其次,它看起来像你将不得不基于检查文本框的内容来选择List的'T',以便你可以处理整数与字符串等。然后将项目分配给该列表基于此。但一旦你决定,你的排序不会在意。

+0

请检查编辑。其面试问题,他们说不使用排序方法,并且输入可能是INTS或小数。 –

+2

@路易斯:在同一时间?对不起,你的问题非常不清楚。 – jason

+0

不,我的想法是,在5个文本框中,一个用户可以输入5个Ints,但另一个用户可以输入5个小数 –

1

你不会用这种正确的方式去做。正确接纳泛型。你想要的是这样的:

public string Foo<T>(IEnumerable<string> strings) where T : struct, IComparable<T> { 
    var list = strings.Select(s => (T)Convert.ChangeType(s, typeof(T))).ToList(); 
    list.Sort((x, y) => (x.CompareTo(y))); 
    return String.Join("\n", list); 
} 

现在你可以说

string response = Foo<int>(strings); 

string response = Foo<decimal>(strings); 

,这取决于你想要的。

注意

  1. 我们使用List<T>.Sort来进行排序。
  2. 我们使用String.Join构建字符串以显示回用户。

这应该编译,但如果没有,请原谅。我现在无法启动ol编译器。

编辑:我看你编辑过,你不能用List<T>.Sort。很容易将我使用的List<T>.Sort替换为您自己的实现。

+0

我明白了,但我的问题是关于如何实例化一个列表,你不知道文本框中的用户是否要输入INTS或小数。 –

+1

@Luis:你是什么意思?用户可以同时输入“int”和“decimal”吗? – jason

+0

不,我的想法是,在5个文本框中,一个用户可以输入5个Ints,但另一个用户可以输入5个小数。 –

0

试着这么做:

private static IList foobar(Type t) 
{ 
    var listType = typeof(List<>); 
    var constructedListType = listType.MakeGenericType(t); 
    var instance = Activator.CreateInstance(constructedListType); 
    return (IList)instance; 
} 

然后使用:

IList list = foobar(TYPE); 

哪里TYPE是要你列出的类型为。

希望这会有所帮助!

相关问题