在C#中访问通用列表中的通用对象

时间:2014-09-16 11:45:38

标签: c# list generics

我对C#比较陌生,我想创建一个通用对象列表。

以下是我尝试的方法:

我创建了一个基类:

public class BaseClass
{
}

我从基类继承了一个泛型类:

public class GenericClass<T> : BaseClass where T: struct
{
    public T data;
    public GenericClass(T value)
    {
        data = value;
    }
    public T doSomething()
    {
        return (T)(data * (dynamic)0.826f);
    }
}

然后我可以创建一个基类列表:

List<BaseClass> ListOfGenericClasses = new List<BaseClass>();

我可以添加继承的基因类的实例:

ListOfGenericClasses.Add(new GenericClass<int>(100));            
ListOfGenericClasses.Add(new GenericClass<byte>(101));
ListOfGenericClasses.Add(new GenericClass<float>(10.1f));
ListOfGenericClasses.Add(new GenericClass<double>(100.10));
ListOfGenericClasses.Add(new GenericClass<ulong>(9999999999));
ListOfGenericClasses.Add(new GenericClass<long>(-9999999999));
ListOfGenericClasses.Add(new GenericClass<uint>(62389));
ListOfGenericClasses.Add(new GenericClass<sbyte>(-103));

我也可以调用每个对象方法:

string s = "";
s += ((GenericClass<int>)(ListOfGenericClasses[0])).doSomething() + " # ";
s += ((GenericClass<byte>)(ListOfGenericClasses[1])).doSomething() + " # ";
s += ((GenericClass<float>)(ListOfGenericClasses[2])).doSomething() + " # ";
s += ((GenericClass<double>)(ListOfGenericClasses[3])).doSomething() + " # ";
s += ((GenericClass<ulong>)(ListOfGenericClasses[4])).doSomething() + " # ";
s += ((GenericClass<long>)(ListOfGenericClasses[5])).doSomething() + " # ";
s += ((GenericClass<uint>)(ListOfGenericClasses[6])).doSomething() + " # ";
s += ((GenericClass<sbyte>)(ListOfGenericClasses[7])).doSomething();
MessageBox.Show(s);

这就是问题所在:我如何获得列表中每个实例的值?

我尝试做这样的事情:

string s = "";
for (int i = 0; i < ListOfGenericClasses.Count; i++)
{
    s += ((GenericClass<ListOfGenericClasses[i].GetType().GetGenericArguments()[0]>)(ListOfGenericClasses[i])).dosdoSomething() + " # ";               
}
MessageBox.Show(s);

我有以下错误消息:&#34;使用泛型类型&#39; GenericClass需要1个类型参数&#39;&#34;

编辑:对不起伙计我在问我的问题时可能会更加精确:我的观点是不是使用返回值来构建字符串,而只是为了在屏幕上看到结果

任何帮助都是非常苛刻的,

提前致谢

5 个答案:

答案 0 :(得分:4)

我以稍微不同的方式接近它:

public class BaseClass
{
     public virtual string DoSomethingToString() { throw new NotImplementedException(); }
}

然后您按如下方式实现派生类:

public class GenericClass<T> : BaseClass where T: struct
{
    public T data;
    public GenericClass(T value)
    {
        data = value;
    }

    public T DoSomething()
    {
        return (T)(data * (dynamic)0.826f);
    }

    public override string DoSomethingToString()
    {
        return DoSomething().ToString();
    }
}

现在您可以迭代List<BaseClass>并直接调用每个元素的DoSomethingToString()方法。

答案 1 :(得分:0)

你应该使用泛型吗?我重新编写了你的​​应用程序并通过删除泛型来解决问题

public class GenericClass : BaseClass
{
    public object data;
    public GenericClass(object value)
    {
        this.data = value;
    }
    public object doSomething()
    {
        return (object)(this.data * (dynamic)0.826f);
    }
}

然后我做到了:

for (var i = 0; i < ListOfGenericClasses.Count; i++)
{
    s += ListOfGenericClasses[i].doSomething() + " # ";
}

答案 2 :(得分:0)

您需要使用反射来获取type,然后从中获取您可以调用的方法:

string s = "";
for (int i = 0; i < ListOfGenericClasses.Count; i++)
{
    s += ListOfGenericClasses[i].GetType()
                       .GetMethod("doSomething")
                       .Invoke(ListOfGenericClasses[i], null);
}

但是,我建议您按照@corak在评论中的建议和@InBetween的答案中采用方法,并在BaseClass中创建虚拟方法并在GenericClass中覆盖它。

答案 3 :(得分:0)

首先使用stringBuilder来连接字符串,你可以将你的对象转换为动态来动态调用你需要的方法:

 var stringbuilder = new StringBuilder();

            foreach (var l in ListOfGenericClasses)
            {
                var st = (l as dynamic).doSomething() + " # ";
                stringbuilder.Append(st);
            }

    MessageBox.Show(stringbuilder.ToString());

答案 4 :(得分:0)

这样做你想要的吗?

string s = "";
for (int i = 0; i < ListOfGenericClasses.Count; i++)
{
    Type type = ListOfGenericClasses[i].GetType();          
    dynamic d = Convert.ChangeType(ListOfGenericClasses[i], type);
    s += d.doSomething() + " # ";               
}

看起来您正在尝试实现联合类型。我相信必须有比这更好的方法。