首页 > 解决方案 > 如何对通用列表对象进行排序

问题描述

我的代码旨在使用具有嵌套类的 json.net 解析未知的 json 文件,并创建复选框以轻松查看它。

在解析过程中的某个时刻,它到达一个 List 对象

我有类型和实际对象

该类型有 AssemblyQualifiedName "System.Collections.Generic.List`1[[Calibration.Camera, CalibrationOrganizer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 "

对象是一个List<Calibration.Camera>

如果我以这种方式遍历列表,它可以工作,但问题是我假设一个已知的数据类型,而我没有。这只是 json 文件中的众多数据类型之一

if (currentType.Name == "List`1")
{
    for (int i = 0; i < ((List<Calibration.Camera>)currentValue).Count; i++)
    {
        cbox = new CheckBox();
        cbox.Text = "[" + i.ToString() + "]";
        cbox.Name = prev_properties + "!" + curr_property;
        cbox.AutoSize = true;
        cbox.Location = new Point(1100 + prop_list.Count() * 100, i++ * 20); //vertical
        cbox.CheckedChanged += new EventHandler(ck_CheckedChanged);
        this.Controls.Add(cbox);
    }   
}

如果我尝试这个,它不会编译

for (int i = 0; i < currentValue.Count; i++) {...}

有错误:Operator '<' cannot be applied to operands of type 'int' and 'method group'

如果我尝试这个,它会崩溃

for (int i = 0; i < ((List<object>)currentValue).Count; i++)

除了:System.InvalidCastException: 'Unable to cast object of type 'System.Collections.Generic.List1[Calibration.Camera]' to type 'System.Collections.Generic.List1[System.Object]'.'

所以我不确定我能做什么,

我可以解析 AssemblyQualifiedName 并将 Object 类型作为字符串获取,但是如何再次将其转换为对象类型?

标签: c#jsonreflection

解决方案


如果你提前施放它会简单得多。例如:

if (currentType.Name == "List`1")
{
    var list = currentValue as List<Calibration.Camera>;
    if (list == null) throw new ArgumentException("currentType and currentValue do not match.");
    foreach (var camera in list)
    {
        cbox = new CheckBox
        {
            Text = "[" + i.ToString() + "]",
            Name = prev_properties + "!" + curr_property,
            AutoSize = true,
            Location = new Point(1100 + prop_list.Count() * 100, i++ * 20) //vertical
        };
        cbox.CheckedChanged += new EventHandler(ck_CheckedChanged);
        this.Controls.Add(cbox);               
    }
}

在此示例中,我们使用“强制转换”as并执行 null 检查以确保它是正确的类型(如果您愿意,可以抛出异常或静默跳过它)。

如果您不确定它是实际的,List<Camera>但您知道它是某种可枚举的,您可以转换为非泛型IEnumerable(not IEnumerable<T>),然后OfType<>在其上使用。这将提取列表中与您想要的类型匹配的任何内容,并将其转换为 generic/typed IEnumerable<T>,然后您可以使用ToList()它。

if (currentType.Name == "List`1")
{
    var enumerable = currentValue as IEnumerable;
    if (enumerable == null) throw new ArgumentException("Doesn't seem to be a list.");
    var list = enumerable.OfType<Calibration.Camera>().ToList();
    foreach (var camera in list)
    {
        //etc....

推荐阅读