访问C#中泛型列表中的泛型对象
本文关键字:泛型 对象 列表 访问 | 更新日期: 2023-09-27 18:22:05
我对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>();
我可以添加继承的geneic类的实例:
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);
我有以下错误消息:"使用泛型类型'GenericClass需要1个类型参数'"
编辑:对不起,伙计们,当我问我的问题时,我本可以更加精确:我的观点不是使用返回值来构建字符串,只是为了在屏幕上看到结果
任何帮助都是值得的,
提前感谢
我会用一种稍微不同的方式来处理它:
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()
方法。
这能满足您的要求吗?
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() + " # ";
}
看起来您正在尝试实现一个联合类型。我相信肯定有比这更好的方法。
是否应该使用泛型?我重新编写了你的应用程序,并通过删除Generics 解决了问题
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() + " # ";
}
您需要使用反射来获取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
中覆盖它。
首先使用stringBuilder来连接字符串,您可以将对象强制转换为dynamic以动态调用所需的方法:
var stringbuilder = new StringBuilder();
foreach (var l in ListOfGenericClasses)
{
var st = (l as dynamic).doSomething() + " # ";
stringbuilder.Append(st);
}
MessageBox.Show(stringbuilder.ToString());