Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在.Net中迭代类的子级?_C#_.net_Class_Serialization - Fatal编程技术网

C# 如何在.Net中迭代类的子级?

C# 如何在.Net中迭代类的子级?,c#,.net,class,serialization,C#,.net,Class,Serialization,我有一个C#.Net类RootObject,它包含许多不同对象类型的列表。我从ajax调用中获取一个json对象,并将其反序列化为一个RootObject实例。我希望迭代根对象中的所有列表,并为它们创建数据表以传递给存储过程,但我不知道如何做到这一点。有人能帮忙吗 public class RootObject { public List<Car> Car { get; set;} public List<Plane> Plane { get; set;}

我有一个C#.Net类RootObject,它包含许多不同对象类型的列表。我从ajax调用中获取一个json对象,并将其反序列化为一个RootObject实例。我希望迭代根对象中的所有列表,并为它们创建数据表以传递给存储过程,但我不知道如何做到这一点。有人能帮忙吗

public class RootObject
{
    public List<Car> Car { get; set;}
    public List<Plane> Plane { get; set;}
    public List<Train> Train { get; set;}
}

    /// <summary>
    /// Returns a data table filled with the values from the input list
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="list"></param>
    /// <returns></returns>
    public DataTable CreateDataTable<T>(IEnumerable<T> list)
    {
        Type type = typeof(T);
        var properties = type.GetProperties();

        DataTable dataTable = new DataTable();
        foreach (PropertyInfo info in properties)
        {
            dataTable.Columns.Add(new DataColumn(info.Name, Nullable.GetUnderlyingType(info.PropertyType) ?? info.PropertyType));
        }

        foreach (T entity in list)
        {
            object[] values = new object[properties.Length];
            for (int i = 0; i < properties.Length; i++)
            {
                values[i] = properties[i].GetValue(entity);
            }

            dataTable.Rows.Add(values);
        }

        return dataTable;
    }



    /// <summary>
    /// This function saves the layout specified by the the user with the ID specified
    /// </summary>
    /// <param name="encryptedBEMSID"></param>
    /// <param name="Layout"></param>
    /// <returns></returns>
    public string Save(string encryptedBEMSID, string Layout)
    {
        // Make a list of table variable parameters to hold the results of the deserialization
        List<SqlParameter> parameters = new List<SqlParameter>();

        // Deserialize the json object
        RootObject obj = JsonConvert.DeserializeObject<RootObject>(Layout);
        PropertyInfo[] objLists = obj.GetType().GetProperties();

        foreach (PropertyInfo pi in objLists)
        {
            string ObjectType = pi.Name; // This would be "Car", "Plane", or "Train"
            string UpperObjectType = ObjectType.ToUpper();

// HERE'S WHERE I NEED HELP! I'd Like to replace Car with the class specified by ObjectType 
            List<Car> List = obj.Car;
            DataTable dt = CreateDataTable<Car>(List);

            // do stuff with the resulting data table

        }
    }

假设你的对象只是{name,color},你可以为它创建一个类,比如说,
Vehicle
,然后反序列化到
字典中

现在,您可以轻松地枚举字典,并枚举每个钥匙的车辆列表

如果它比您展示的JSON更复杂,那么您最好直接阅读JSON(使用JSON.NET)并以这种方式处理它

您还可以向JSON中添加一个类型鉴别器(请参阅),然后JSON.NET将知道
Car
字段包含
Car
对象(这是一个隐含的事实,但在当前的JSON模式中没有说明)。您还可以提供一个自定义序列化绑定器,用于处理由字段名定义的类型的特殊情况。您仍然需要一个基类
Vehicle
,但实际的反序列化值将是预期的类型


另外,另一种选择可能是使用
字典
保存反序列化的JSON,因为您所做的一切都是将值复制到表中——您不在乎它是
汽车
,它只是一个名称和值的集合。

如果将数据表创建移动到一个泛型类
VehicleHandler
中,则可以创建一个实例,其类型与当前正在检查的属性类型相匹配,如下所示:-

Type vehicleListType = pi.PropertyType;
Type vehicleType = vehicleListType.GetGenericArguments()[0];
var vehicleHandlerType = typeof (VehicleHandler<>).MakeGenericType(vehicleType);
var vehicleHandler = (VehicleHandler)Activator.CreateInstance(vehicleHandlerType);
VehicleHandler的代码为:

public abstract class VehicleHandler
{
    public abstract void SetVehicles(object listOfVehicles);
    public abstract DataTable DataTable { get; }
}

public class VehicleHandler<T> : VehicleHandler
{
    List<T> vehicles;

    public override void SetVehicles (object listOfVehicles)
    {
        this.vehicles = (List<T>) listOfVehicles;
    }

    public override DataTable DataTable => CreateDataTable(vehicles);

    public DataTable CreateDataTable(IEnumerable<T> list)
    {
        Type type = typeof (T);
        var properties = type.GetProperties();

        DataTable dataTable = new DataTable();
        foreach (PropertyInfo info in properties)
        {
            dataTable.Columns.Add(new DataColumn(info.Name,
                Nullable.GetUnderlyingType(info.PropertyType) ?? info.PropertyType));
        }

        foreach (T entity in list)
        {
            object[] values = new object[properties.Length];
            for (int i = 0; i < properties.Length; i++)
            {
                values[i] = properties[i].GetValue(entity);
            }

            dataTable.Rows.Add(values);
        }

        return dataTable;
    }

}
公共抽象类VehicleHandler
{
公共车辆(车辆对象列表);
公共抽象数据表{get;}
}
公共类VehicleHandler:VehicleHandler
{
列出车辆清单;
公共车辆(车辆对象列表)
{
本表车辆=(列表)车辆清单;
}
公共覆盖数据表=>CreateDataTable(车辆);
公共数据表CreateDataTable(IEnumerable列表)
{
类型=类型(T);
var properties=type.GetProperties();
DataTable=新的DataTable();
foreach(属性中的属性信息)
{
dataTable.Columns.Add(新建DataColumn(info.Name,
null.getUnderlineType(info.PropertyType)??info.PropertyType));
}
foreach(列表中的T实体)
{
object[]value=新对象[properties.Length];
for(int i=0;i
请发布JSON示例,以便我们能更好地帮助您?“我想迭代所有列表”-
RootObject ro=newrootobject();foreach(Car-Car-in-ro.Car){//do something}
?@Tim它不是迭代列表中我遇到问题的项目,而是迭代列表本身。我不想显式地输入ro.Car、ro.Plane和ro.Train(我的实际用例有几十种这种类型)。如果您使用的是JSON.NET,那么可以使用
JObject.Parse
来获取可枚举对象。使用
foreach
迭代键/值对-键将是“Car”、“Plane”和“Train”,而值将是包含项目的数组。您从哪里获得
车辆
?它将是save方法中的
对象列表
,否?是的,我做作而简单的例子过于简化了。在我的实际案例中,每个对象的属性都有很大的不同。假设我有一个所有其他类都可以继承的基类,我仍然不清楚如何将(?)对象转换为它们的实际类型。你是一个了不起的人。非常感谢!明天早上我第一件事就是试试。再次感谢!
Type vehicleListType = pi.PropertyType;
Type vehicleType = vehicleListType.GetGenericArguments()[0];
var vehicleHandlerType = typeof (VehicleHandler<>).MakeGenericType(vehicleType);
var vehicleHandler = (VehicleHandler)Activator.CreateInstance(vehicleHandlerType);
vehicleHandler.SetVehicles(pi.GetValue(obj));
var dataTable = vehicleHandler.DataTable;
public abstract class VehicleHandler
{
    public abstract void SetVehicles(object listOfVehicles);
    public abstract DataTable DataTable { get; }
}

public class VehicleHandler<T> : VehicleHandler
{
    List<T> vehicles;

    public override void SetVehicles (object listOfVehicles)
    {
        this.vehicles = (List<T>) listOfVehicles;
    }

    public override DataTable DataTable => CreateDataTable(vehicles);

    public DataTable CreateDataTable(IEnumerable<T> list)
    {
        Type type = typeof (T);
        var properties = type.GetProperties();

        DataTable dataTable = new DataTable();
        foreach (PropertyInfo info in properties)
        {
            dataTable.Columns.Add(new DataColumn(info.Name,
                Nullable.GetUnderlyingType(info.PropertyType) ?? info.PropertyType));
        }

        foreach (T entity in list)
        {
            object[] values = new object[properties.Length];
            for (int i = 0; i < properties.Length; i++)
            {
                values[i] = properties[i].GetValue(entity);
            }

            dataTable.Rows.Add(values);
        }

        return dataTable;
    }

}