如何在不知道类型的情况下实例化通用列表

时间:2011-09-27 14:40:15

标签: c# .net generics

我创建了一个方法来组织通用列表而不知道类型,如果是int或decimal,它会排序。

但是,从文本框中检索值的代码使用List

我尝试将其转换为List,但它不起作用。 如果他们在文本框中键入整数或小数或字符串,我希望此代码有效。

这是面试问题的一部分,他们要求不使用排序方法,输入应该接收例如INTS或DECIMALS

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);         排序(列表);

4 个答案:

答案 0 :(得分:3)

  

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

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

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

修改

你必须编写自定义代码来确定输入是字符串,整数还是十进制,即使用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} );

我很确定这不是想要的面试问题要求的。

答案 1 :(得分:1)

首先,正如杰森指出的那样,让平台为你工作 - 打电话.Sort。

其次,在我看来,你必须根据检查文本框的内容来选择列表的'T',这样你就可以处理整数和字符串等。然后将项目分配给列表基于此。但是一旦你决定了,你的分类就不在乎了。

答案 2 :(得分: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构建字符串以显示给用户。
  3. 这应该编译,但如果没有,请原谅琐碎的错误。我现在无法启动ol'编译器。

    编辑:我看到你编辑了,因为你无法使用List<T>.Sort。使用您自己的实现替换List<T>.Sort的使用很容易。

答案 3 :(得分: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是您希望列出的类型。

希望这有帮助!