接收任何类型对象并将对象转换为List <string> </string>的通用方法

时间:2009-11-05 00:24:45

标签: c# generics

再次编辑:解决方案可能与我原来的问题有所不同。非常感谢大家的好主意。我希望我能投票给不止一个答案。

编辑:我正在从datatables / .net填充Jquery表插件,它要求数据(Json)采用这样的特定格式;

    "sEcho": 1,
    "iTotalRecords": 57,
    "iTotalDisplayRecords": 57,
    "aaData": [
        [
            "Gecko",
            "Firefox 1.0",
            "Win 98+ / OSX.2+",
            "1.7",
            "A"
        ],
        [
            "Gecko",
            "Firefox 1.5",
            "Win 98+ / OSX.2+",
            "1.8",
            "A"
        ],
        ...
    ] 
}

我从正在返回对象集合的服务中收到数据。我想要一个方法,我可以将这些集合传递给它,它将返回相应的字符串

感谢 结束编辑 我想构建一个方法,可以接收和构建我们构建的对象,并返回一个数组List,每个包含传入的每个对象的值。例如;

我有一个'Car'对象的集合

我想做的是

public object[] Something<T>(_cars)
{
    object[] objArray = new object[_cars.Count];
    foreach(Car _car in _cars ){
    IList objList = new List<string>;
    objList.Add(_car.Color);
    objList.Add(_car.EngineSize);
    //etc etc
    objArray[i] = objList;//i'll have to use a for loop to get the i counter but you get my idea
   }
    return objArray
}

我的问题是如何在不知道它是什么类型的对象的情况下访问对象的属性?

感谢您的帮助

6 个答案:

答案 0 :(得分:3)

更新:要回答修改后的问题 - 生成数据结构的JSON结果 - 使用内置的JavaScriptSerializer类:

JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = seriaizer.Serialize(myObjectOrArray);

以下是上一个答案。

  

如何在不知道对象的类型

的情况下访问对象的属性

使用Reflection,并获取字符串属性。请注意,这不一定是个好主意。事实上你必须使用反射来获得你想要的东西通常是巨大的警告标志,你的设计是错误的。

但是,希望学习一些有用的东西,以下是可以的完成方式:

public object[] Something<T>(T[] items)
{
    IList objList = new List<object>();
    //get the properties on which are strings
    PropertyInfo[] properties = typeof(T).GetProperties().Where(p => p.PropertyType == typeof(string));
    foreach(T item in items)
    {
        IList stringList = new List<string>;
        foreach(PropertyInfo property in properties)
        {
            objList.Add(property.GetValue(item, null) as string);
        }
        objList.Add(stringList);
    }
   }
   return objList.ToArray();
}

一个远远好得多的解决方案是要求所有进入此方法的对象符合某些要求它们提供自己的字符串格式数据的接口。 可能会退回两步并就潜在问题寻求帮助。这种方法充满了问题。这是一个你不想放下的兔子洞。

答案 1 :(得分:2)

使用System.Web.Script.Serialization.JavaScriptSerializer课程。它专门为JSON序列化提供。

using System.Web.Script.Serialization;

public string ToJson(object o)
{
  JavaScriptSerializer serializer = new JavaScriptSerializer();
  return serializer.Serialize(o);
}

编辑:糟糕,我错过了你的插件不想要对象的真正JSON表示;它只是想要数组的值。您可以使用反射来迭代对象的属性,但是您无法控制哪些属性最终会出现在哪些列中。你的问题不清楚这是否对你有用。

如果您需要在属性和列之间进行严格的映射,那么您必须在C#中以某种方式定义它。为此,您可以在Ed演示或创建自定义界面时实现IEnumerable

public interface ITableDataSource
{
  IList<string> GetTableData();
}

然后在任何可能需要作为jQuery表插件的数据源的对象上实现:

public class Car : ITableDataSource
{
  //...class implementation details...

  public IList<string> GetTableData()
  {
    return new List<string>()
    {
      this.Color,
      this.EngineSize,
      this.NumberOfSeats.ToString()
    };
  }
}

最后,在将数据返回到jQuery插件的方法中,使用接口构建响应对象,然后将其传递给我的ToJson()方法以序列化它:

public string DoSomething(IList<ITableDataSource> objects)
{
  var result = new 
  {
    sEcho = 1,
    iTotalRecords = 1,
    iTotalDisplayRecords = 1,
    aaData = new List<IList<string>>()
  };
  foreach (ITableDataSource ds in objects)
    result.aaData.Add(ds.GetTableData());

  return ToJson(result);
}

答案 2 :(得分:1)

虽然使用反射来遍历所有对象以及这些对象上的所有属性以构建该字符串是相对简单的,但它已经被编写了。

我强烈建议查看here找到的Json.NET项目。将此DLL添加到项目中,将对象列表转换为Json格式的字符串非常简单:

string json = Newtonsoft.Json.JsonConvert.SerializeObject( listOfCars );

答案 3 :(得分:0)

IList objList = new List<string>();
foreach ( PropertyInfo prop in _car.GetType().GetProperties() )
{
    var value = prop.GetValue( _car, null );
    objList.Add( value != null ? value.ToString() : null );
}
objArray[i] = objList;

答案 4 :(得分:0)

  

我的问题是如何在不知道它是什么类型的对象的情况下访问对象的属性?

嗯,一般来说你不能。泛型是关于一般地处理对象的全部内容。但是,您可以使用where子句强加类型约束。基于foreach循环,我会说你的类型约束到实现IEnumerable的类型,但是你继续使用像“Color”和“EngineSize”这样的属性,这些属性非常具体。我甚至不知道为什么你会将名为“Color”和“EngineSize”的属性作为字符串,但这完全是另一个问题......

似乎最好的方法是定义每个对象继承的接口或抽象基类。然后你可以使用'where'子句来限制那个接口/基类的对象只有......

public object[] Something<T>( T _cars) where T : IEnumerable<MyInterface>

然而,如果我们要走这条路,我不明白为什么这个方法应该是通用的。它可以简单地将IEnumerable<T>作为输入。当我们只想在方法中使用一种类型时,不需要泛型。

答案 5 :(得分:0)

获取对象的Property值的代码是

foreach (PropertyInfo info in myObject.GetType().GetProperties())
{
   if (info.CanRead)
   {
      object o = propertyInfo.GetValue(myObject, null);
   }
}