簡體   English   中英

在C#中訪問通用列表中的通用對象

[英]Accessing generic object in generic list in C#

我是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);

我收到以下錯誤消息:“使用通用類型'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()方法。

您應該使用泛型嗎? 我重新編寫了您的應用,並通過刪除泛型來解決了問題

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

這是您想要的嗎?

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

看來您正在嘗試實現聯合類型。 我相信必須有比這更好的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM