簡體   English   中英

C#將MyType的列表轉換為對象列表

[英]C# Cast List of MyType to List of objects

我正在編寫一個應用程序,我需要使用Reflection來調用一個具有MyObject類型參數的方法。

Method (List<MyObject> input , out List<MyObject> output,..... );

使用反射我發送Object類型的參數。 如何將List<MyObject>List<object>

var parameters = new Object[] { inputs, outputs, userPrams };
System.Type classType = typeof(MyClass);
object instance = Activator.CreateInstance(classType);
classType.InvokeMember(name, BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,null, instance, parameters);

在上面的代碼中,輸入和輸出都是MyObject類型的列表

我試圖將它們轉換為對象列表,但這不起作用

x.Outputs = grOutputs as IList<object>

有人可以幫忙嗎?

你的問題不是100%明確,所以我認為你面臨的問題是你在標題中提出的問題:

將MyType的列表轉換為對象列表

正如@Charles所說, IList<T>List<T>不是變體,因此您無法將IList<DerivedClass>IList<BaseClass> 您必須創建新的List<BaseClass>

有很多方法可以做到這一點,我認為你應該考慮兩個:

  1. 您可以使用CastToList ,但需要using System.Linq

     var listOfStrings = new List<string>() { "foo", "bar" }; var listOfObjects = listOfStrings.Cast<object>().ToList(); 
  2. 為避免這種情況,您可以使用new List<T>(IEnumerable<T> source)構造函數。 因為IEnumerable<T>是協變的,所以你可以這樣做:

     var listOfStrings = new List<string>() { "foo", "bar" }; var listOfObjects = new List<object>(listOfString); 

你可能想做這樣的事情:

var dogs = new List<Dog>();
var pets = (List<object>)dogs;
pets.Add(new Cat());

C#語言投入大量資金用於停止像這樣的貓狗混合。 它違反了列表只包含狗的硬保證。 你必須這樣做:

var dogs = new List<Dog>();
var pets = new List<object>(dogs);
pets.Add(new Cat());

哪個好,它會創建一個新的列表,不再保證它只包含狗,因為它只承諾列表包含對象 相當無用,通常,你基本上都不知道列表包含的內容。 強迫你編寫使用as運算符或Reflection的hunt-the-fox代碼來找回適當的動物。 代碼在運行時無法完成其工作,而不是編譯器在構建時告訴您錯誤的代碼,當您仍在舒適的隔間繭中時。

它做了什么。

IList<T>不是協變的,如果你想要IList<object> ,你需要創建一個新的列表:

x.Outputs = grOutputs.Cast<object>().ToList();

您無法進行所需的演員表,因為正如其他人所寫,c#中的集合不是協變的

您可以創建新列表,也可以像這樣引入ListWrapper類:

public class ListWrapper<TOut, TIn> : IList<TOut> where TIn : class, TOut where TOut : class 
{
    readonly IList<TIn> list;

    public ListWrapper(IList<TIn> list)
    {
        if (list == null)
            throw new NullReferenceException();
        this.list = list;
    }

    #region IList<TOut> Members

    public int IndexOf(TOut item)
    {
        TIn itemIn = item as TIn;
        if (itemIn != item)
            return -1;
        return list.IndexOf(itemIn);
    }

    public void Insert(int index, TOut item)
    {
        list.Insert(index, (TIn)item);
    }

    public void RemoveAt(int index)
    {
        list.RemoveAt(index);
    }

    public TOut this[int index]
    {
        get
        {
            return list[index];
        }
        set
        {
            list[index] = (TIn)value;
        }
    }

    #endregion

    #region ICollection<TOut> Members

    public void Add(TOut item)
    {
        list.Add((TIn)item);
    }

    public void Clear()
    {
        list.Clear();
    }

    public bool Contains(TOut item)
    {
        TIn itemIn = item as TIn;
        if (itemIn != item)
            return false;
        return list.Contains(itemIn);
    }

    public void CopyTo(TOut[] array, int arrayIndex)
    {
        foreach (var item in list)
        {
            array[arrayIndex] = item;
            arrayIndex++;
        }
    }

    public int Count
    {
        get { return list.Count; }
    }

    public bool IsReadOnly
    {
        get
        {
            return list.IsReadOnly;
        }
    }

    public bool Remove(TOut item)
    {
        return list.Remove(item as TIn);
    }

    #endregion

    #region IEnumerable<TOut> Members

    public IEnumerator<TOut> GetEnumerator()
    {
        foreach (var item in list)
            yield return item;
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion
}

您可能希望將包裝器設置為只讀,因為如果傳入的對象不是內部列表的項類型,則setter可能會拋出異常。

如果我理解你的問題,你可以嘗試這樣的事情:

var objList = myClassList.OfType<object>();

暫無
暫無

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

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