从PHP的世界来看,我决定给C#一个机会。我有一个搜索,但似乎无法找到如何做到与此相当的答案。
$object = new Object();
$vars = get_class_vars(get_class($object));
foreach($vars as $var)
{
doSomething($object->$var);
}
我基本上有一个对象列表。该对象可以是三种不同类型之一,并且具有一组公共属性。我希望能够获得对象的属性列表,循环它们然后将它们写入文件。 我认为这与c#反射有关,但这对我来说都是新的。
非常感谢任何帮助。
答案 0 :(得分:247)
这应该这样做:
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
}
答案 1 :(得分:17)
是的,反思将是要走的路。首先,您将获得表示列表中实例的类型(在运行时)的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
运算符帮助确定您在运行时使用的基类/接口。)
但是,如果你不控制这些类型定义并且必须根据模式匹配来驱动逻辑,那就没关系。
答案 2 :(得分:15)
void Test(){
var obj = new{a="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 :(得分:10)
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));
}
答案 4 :(得分:8)
从属性名称
获取特定属性值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);
}
答案 5 :(得分:3)
您可以使用 GetType - GetProperties - Linq Foreach :
obj.GetType().GetProperties().ToList().ForEach(p =>{
//p is each PropertyInfo
DoSomething(p);
});
答案 6 :(得分:2)
我使用以下内容将IEnumerable<T>
转换为DataTable
,其中包含代表T
属性的列,IEnumerable
中的每个项都有一行:< / p>
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:
Make(string)
YearOfManufacture(int)
List<Car>
答案 7 :(得分:1)
此示例修剪对象的所有字符串属性。
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);
}
}
答案 8 :(得分:0)
我还没有找到这个,比如Application对象。然而,我已经取得了成功
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string rval = serializer.Serialize(myAppObj);
答案 9 :(得分:0)
使用Linq的一线解决方案...
var obj = new {Property1: 1, Property2: 2};
var property1 = obj.GetType().GetProperties().First(o => o.Name == "Property1").GetValue(obj , null);
答案 10 :(得分:0)
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;
}
答案 11 :(得分:0)
from django.db.models import Max
Users.objects.all().aggregate(Max('Events.timestamp'))
答案 12 :(得分:-1)
你可以试试这个:
string[] arr = ((IEnumerable)obj).Cast<object>()
.Select(x => x.ToString())
.ToArray();
每个数组实现IEnumerable接口
答案 13 :(得分:-1)
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;