[英]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>
。
有很多方法可以做到這一點,我認為你應該考慮兩個:
您可以使用Cast
和ToList
,但需要using System.Linq
。
var listOfStrings = new List<string>() { "foo", "bar" }; var listOfObjects = listOfStrings.Cast<object>().ToList();
為避免這種情況,您可以使用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.