【问题标题】:Getting type of List<object> that is empty获取空的 List<object> 类型
【发布时间】:2021-03-06 00:06:27
【问题描述】:
List<SomeClass> classObject = new List<SomeClass>();
someClass = .....
classObject.Add(someClass);

// For some reason we need to cast this List to List<object>.
List<object> objectList = classObject.Cast<object>().ToList();

// The receiving end will try then cast the item using the items in the objectList
var newInstance = Assembly.GetExecutingAssembly().CreateInstance(objectList[index].GetType().FullName);

除了列表为空之外的所有工作,接收端无法在不知道预期实例的全名的情况下投射新实例。

在没有传递 someClass 的类型的情况下,它周围有没有?

我尝试过 GetGenericArguments 但失败了,因为它返回了我们无法使用的 System.Object。

【问题讨论】:

  • 在尝试访问其项目之前没有检查列表是否为空?
  • 我会猜测并说“不”,没有办法。您的列表是object 类型之一,如果不包含someClass 的实例,则可能包含或多或少的任何内容。编译器应该如何知道您打算使用什么类型,或者曾经保存在您的列表中?
  • @ChetanRanpariya 上面的示例是在他们检查另一个扩展类执行的列表是否不为空之后。我们在这里试图解决的问题是找到一种方法来获取列表中没有对象的对象类型。我们确实知道列表中只有一种类型的对象。
  • @GeorgeKerwood 嗨,Geroge,我们也这么认为,因为它已经是一个基础对象并且没有解决方法。猜猜在这种情况下我们也必须传递类型,但这确实需要大量重构。我们有一个扩展类,可以将类转换为数据表、列表、xml、模型等。除了这个列表问题之外,所有部分都可以正常工作,因为我们无法使用空列表构建正确的数据表。 :(
  • 如果列表为空,尝试从列表中的一个现有项目创建对象的目的是什么?当您尝试通过执行 objectList[index] 来访问空列表中的项目时,您没有遇到异常吗?

标签: c# list casting


【解决方案1】:

首先警告我认为这是一个“hacky”解决方案,但是你要求一种方法,所以它就是这样。

问题是List&lt;object&gt; 不包含我们需要的信息。如果列表中有项目,您可以通过检查项目来解决此问题,但如果列表中没有项目,这显然不起作用。

因此,我们需要创建一种将所需信息添加到 List&lt;object&gt; 的方法,我们可以通过创建自己的 List&lt;object&gt; 来做到这一点:

public class MyTypedObjectList : List<object>
{
    public MyTypedObjectList(Type type)
    {
        MyType = type;
    }
    public Type MyType { get; }
}

为了便于使用,我们可以创建一个扩展方法来为我们创建:

public static class EnumerableExtensions
{
    public static MyTypedObjectList ToMyTypedObjectList<T>(this IEnumerable<T> source)
    {
        var myTypedObjectList = new MyTypedObjectList(typeof(T));
        myTypedObjectList.AddRange(source.Cast<object>());
        return myTypedObjectList;
    }
}

现在我们可以这样做了:

List<object> objectList = classObject.ToMyTypedObjectList();

并在其余代码中将其用作List&lt;object&gt;

然后在接收端(因为我们使用的是同一个实例),即使列表为空,我们也可以回滚并获取类型:

var myTypedObjectList = (MyTypedObjectList) objectList;

最后这样做:

Assembly.GetExecutingAssembly().CreateInstance(myTypedObjectList.MyType.FullName);

正如所说,这是一种 hacky 方式,但如果你真的想这样做应该可以解决你的问题(但请考虑重构并以正确的方式解决这个问题)

【讨论】:

  • 感谢您的努力,虽然老套但有效。由于当前的源代码(我相信)在自定义扩展之前将每个 fking List 转换为 List,现在快速搜索和替换加上 4 块代码就可以了!
猜你喜欢
  • 2021-09-11
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
  • 2018-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
相关资源
最近更新 更多