[英]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.