从未知对象获取属性和值
Posted
技术标签:
【中文标题】从未知对象获取属性和值【英文标题】:Get properties and values from unknown object 【发布时间】:2010-11-10 13:11:02 【问题描述】:从 php 的世界开始,我决定尝试 C#。我已经进行了搜索,但似乎找不到如何做到这一点的答案。
$object = new Object();
$vars = get_class_vars(get_class($object));
foreach($vars as $var)
doSomething($object->$var);
我基本上有一个对象列表。该对象可以是三种不同类型中的一种,并将具有一组公共属性。我希望能够获取对象的属性列表,遍历它们,然后将它们写到文件中。 我认为这与 c# 反射有关,但这对我来说是全新的。
任何帮助将不胜感激。
【问题讨论】:
附带说明:在列表中包含不同类型的对象(没有公共基类或接口)不是一种好的编程风格,至少在 c# 中不是。 【参考方案1】:应该这样做:
Type myType = myObject.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
foreach (PropertyInfo prop in props)
object propValue = prop.GetValue(myObject, null);
// Do something with propValue
【讨论】:
@jonathanSystem.Reflection
命名空间
实际上不需要从数组创建列表,只需PropertyInfo[] props = input.GetType().GetProperties();
您想使用 Newtonsoft.Json.JsonConvert
更新 2017 年的答案吗?
@clone 这是一种完全不同的方式。如果您认为这是一种有效的方法,您应该发布答案
@Jonesopolis 如何从dynamic
获取属性,而不先将其转换为object
,然后按照我的答案进行操作?【参考方案2】:
void Test()
var obj = newa="aaa", b="bbb";
var val_a = obj.GetValObjDy("a"); //="aaa"
var val_b = obj.GetValObjDy("b"); //="bbb"
//create in a static class
static public object GetValObjDy(this object obj, string propertyName)
return obj.GetType().GetProperty(propertyName).GetValue(obj, null);
【讨论】:
【参考方案3】:是的,反射将是要走的路。首先,您将获得Type
,它表示列表中实例的类型(在运行时)。您可以通过拨打GetType
method on Object
来完成此操作。因为它在Object
类上,它可以被.NET 中的每个 对象调用,因为所有类型都派生自Object
(well, technically, not everything,但这在这里并不重要)。
拥有Type
实例后,您可以调用GetProperties
method 来获取PropertyInfo
实例,这些实例代表关于Type
上的属性的运行时信息。
注意,您可以使用 GetProperties
的重载来帮助分类您检索到的哪些属性。
从那里,您只需将信息写入文件。
您上面的代码,翻译后将是:
// The instance, it can be of any type.
object o = <some object>;
// Get the type.
Type type = o.GetType();
// Get all public instance properties.
// Use the override if you want to classify
// which properties to return.
foreach (PropertyInfo info in type.GetProperties())
// Do something with the property info.
DoSomething(info);
请注意,如果您需要方法信息或字段信息,则必须分别调用 GetMethods
或 GetFields
方法的重载之一。
另请注意,将成员列出到文件中是一回事,但您不应该使用此信息来驱动基于属性集的逻辑。
假设您可以控制类型的实现,您应该从一个公共基类派生或实现一个公共接口并对它们进行调用(您可以使用as
或is
运算符来帮助确定哪个您在运行时使用的基类/接口)。
但是,如果您不控制这些类型定义并且必须基于模式匹配来驱动逻辑,那也没关系。
【讨论】:
【参考方案4】:嗯,在 C# 中也是类似的。 这是最简单的示例之一(仅适用于公共属性):
var someObject = new .../*properties*/... ;
var propertyInfos = someObject.GetType().GetProperties();
foreach (PropertyInfo pInfo in propertyInfos)
string propertyName = pInfo.Name; //gets the name of the property
doSomething(pInfo.GetValue(someObject,null));
【讨论】:
【参考方案5】:从属性名称中获取特定的属性值
public class Bike
public string Name get;set;
Bike b = new Bike Name = "MyBike";
从属性的字符串名称访问Name的属性值
public object GetPropertyValue(string propertyName)
//returns value of property Name
return this.GetType().GetProperty(propertyName).GetValue(this, null);
【讨论】:
【参考方案6】:使用 Linq 的单行解决方案...
var obj = new Property1 = 1, Property2 = 2;
var property1 = obj.GetType().GetProperties().First(o => o.Name == "Property1").GetValue(obj , null);
【讨论】:
【参考方案7】:您可以使用GetType - GetProperties - Linq Foreach:
obj.GetType().GetProperties().ToList().ForEach(p =>
//p is each PropertyInfo
DoSomething(p);
);
【讨论】:
【参考方案8】:这是我用来将IEnumerable<T>
转换为DataTable
的东西,其中包含代表T
属性的列,IEnumerable
中的每个项目都有一行:
public static DataTable ToDataTable<T>(IEnumerable<T> items)
var table = CreateDataTableForPropertiesOfType<T>();
PropertyInfo[] piT = typeof(T).GetProperties();
foreach (var item in items)
var dr = table.NewRow();
for (int property = 0; property < table.Columns.Count; property++)
if (piT[property].CanRead)
var value = piT[property].GetValue(item, null);
if (piT[property].PropertyType.IsGenericType)
if (value == null)
dr[property] = DBNull.Value;
else
dr[property] = piT[property].GetValue(item, null);
else
dr[property] = piT[property].GetValue(item, null);
table.Rows.Add(dr);
return table;
public static DataTable CreateDataTableForPropertiesOfType<T>()
DataTable dt = new DataTable();
PropertyInfo[] piT = typeof(T).GetProperties();
foreach (PropertyInfo pi in piT)
Type propertyType = null;
if (pi.PropertyType.IsGenericType)
propertyType = pi.PropertyType.GetGenericArguments()[0];
else
propertyType = pi.PropertyType;
DataColumn dc = new DataColumn(pi.Name, propertyType);
if (pi.CanRead)
dt.Columns.Add(dc);
return dt;
这“有点”过于复杂,但它实际上非常适合查看结果,因为您可以给它一个List<T>
,例如:
public class Car
string Make get; set;
int YearOfManufacture get; set;
您将返回一个具有以下结构的 DataTable:
制作(字符串) YearOfManufacture (int)
List<Car>
中的每一项都包含一行
【讨论】:
【参考方案9】:此示例修剪对象的所有字符串属性。
public static void TrimModelProperties(Type type, object obj)
var propertyInfoArray = type.GetProperties(
BindingFlags.Public |
BindingFlags.Instance);
foreach (var propertyInfo in propertyInfoArray)
var propValue = propertyInfo.GetValue(obj, null);
if (propValue == null)
continue;
if (propValue.GetType().Name == "String")
propertyInfo.SetValue(
obj,
((string)propValue).Trim(),
null);
【讨论】:
【参考方案10】:我还没有发现这个可以工作,比如应用程序对象。然而,我已经成功了
var serializer = new System.Web.Script.Serialization.javascriptSerializer();
string rval = serializer.Serialize(myAppObj);
【讨论】:
如果可以避免,请不要使用 JavaScriptSerializer。 There are great many reasons.【参考方案11】:你可以试试这个:
string[] arr = ((IEnumerable)obj).Cast<object>()
.Select(x => x.ToString())
.ToArray();
一旦每个数组都实现了 IEnumerable 接口
【讨论】:
【参考方案12】:public Dictionary<string, string> ToDictionary(object obj)
Dictionary<string, string> dictionary = new Dictionary<string, string>();
Type objectType = obj.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(objectType.GetProperties());
foreach (PropertyInfo prop in props)
object propValue = prop.GetValue(obj, null);
dictionary.Add(prop.Name, propValue.ToString());
return dictionary;
【讨论】:
【参考方案13】: /// get set value field in object to object new (two object field like )
public static void SetValueObjectToObject (object sourceObj , object resultObj)
IList<PropertyInfo> props = new List<PropertyInfo>(sourceObj.GetType().GetProperties());
foreach (PropertyInfo prop in props)
try
//get value in sourceObj
object propValue = prop.GetValue(sourceObj, null);
//set value in resultObj
PropertyInfo propResult = resultObj.GetType().GetProperty(prop.Name, BindingFlags.Public | BindingFlags.Instance);
if (propResult != null && propResult.CanWrite)
propResult.SetValue(resultObj, propValue, null);
catch (Exception ex)
// do something with Ex
【讨论】:
以上是关于从未知对象获取属性和值的主要内容,如果未能解决你的问题,请参考以下文章