繁体   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