Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中访问泛型列表中的泛型对象_C#_List_Generics - Fatal编程技术网

C# 在C中访问泛型列表中的泛型对象

C# 在C中访问泛型列表中的泛型对象,c#,list,generics,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()

我对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>();
我从基类继承了一个泛型类:

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>();
然后我可以创建一个基类列表:

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 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() + " # ";
}

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

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() + " # ";
}

我会用一种稍微不同的方式:

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();
    }
}

现在,您可以迭代列表并直接调用每个元素的DoSomethingToString方法。

我将以稍微不同的方式处理它:

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();
    }
}

现在,您可以迭代列表并直接调用每个元素的DoSomethingToString方法。

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

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

但是,我建议您采用@corak在评论中以及@InBetween在回答中建议的方法,在基类中创建一个虚拟方法,并在GenericClass中重写它。

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

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());

首先使用stringBuilder连接字符串,您可以将对象强制转换为动态,以动态调用所需的方法:

 var stringbuilder = new StringBuilder();

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

    MessageBox.Show(stringbuilder.ToString());

这是你想要的吗

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() + " # ";               
}

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

这是你想要的吗

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() + " # ";               
}

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

在这种情况下,我可能会在基类内有一个公共虚拟字符串DoSomethingString{return null;},在GenericClass内有一个公共重写字符串DoSomethingString{return doSomething.ToString;}。您希望如何处理该值?您需要将其作为字符串或?顺便说一句,随着列表变大,将字符串添加到一起会变得非常缓慢,因为每次都会创建一个新的字符串对象。使用StringBuilder,或者如果您按照我的建议,您可以执行类似字符串s=string.Join、ListofGenericClass.Selectitem=>item.DoSomethingString;的操作;。在这种情况下,我可能会在基类内有一个公共虚拟字符串DoSomethingString{return null;},在GenericClass内有一个公共重写字符串DoSomethingString{return doSomething.ToString;}。您希望如何处理该值?您需要将其作为字符串或?顺便说一句,随着列表变大,将字符串添加到一起会变得非常缓慢,因为每次都会创建一个新的字符串对象。使用StringBuilder,或者如果您按照我的建议,您可以执行类似字符串s=string.Join、ListofGenericClass.Selectitem=>item.DoSomethingString;的操作;。没错,你可以这样做,但如果你关心拳击,那就不是最佳解决方案。没错,你可以这样做,但如果你关心拳击,那么这不是最佳解决方案。我认为这是最干净的方法+1可能想给你的虚拟方法一个返回类型:我认为这是最干净的方法+1可能想给你的虚拟方法一个返回类型:你的解决方案也可以:我不能接受多个,对不起,你的解决方案也可以,我只能接受多个对不起,你的解决办法也行,我只能接受一个。对不起,你的解决办法也行,我只能接受一个