我正在编写一个应用程序,我需要使用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>
有人可以帮忙吗?
答案 0 :(得分:7)
你的问题不是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);
答案 1 :(得分:3)
你可能想做这样的事情:
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());
哪个好,它会创建一个 new 列表,不再保证它只包含狗,因为它只承诺列表中包含 object 。相当无用,通常,你基本上都不知道列表包含的内容。强迫你编写使用作为运算符或反射来寻找合适动物的猎狐代码。代码在运行时无法完成其工作,而不是编译器在构建时告诉您错误的代码,当您仍在舒适的隔间茧中时。
它做了什么。
答案 2 :(得分:2)
IList<T>
不是协变的,如果您需要IList<object>
,则需要创建一个新列表:
x.Outputs = grOutputs.Cast<object>().ToList();
答案 3 :(得分:0)
您无法进行所需的演员表,因为正如其他人所写,c#中的集合不是covariant。
您可以创建新列表,也可以像这样引入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可能会抛出异常。
答案 4 :(得分:-1)
如果我理解你的问题,你可以尝试这样的事情:
var objList = myClassList.OfType<object>();