我需要调整一堆对象的日期时间。
我想循环遍历类的属性,如果类型是dateTime,则相应调整。
我可以使用任何形式的“描述类型”吗?
答案 0 :(得分:24)
您可以使用reflection。
您的方案可能看起来像这样:
static void Main(string[] args)
{
var list = new List<Mammal>();
list.Add(new Person { Name = "Filip", DOB = DateTime.Now });
list.Add(new Person { Name = "Peter", DOB = DateTime.Now });
list.Add(new Person { Name = "Goran", DOB = DateTime.Now });
list.Add(new Person { Name = "Markus", DOB = DateTime.Now });
list.Add(new Dog { Name = "Sparky", Breed = "Unknown" });
list.Add(new Dog { Name = "Little Kid", Breed = "Unknown" });
list.Add(new Dog { Name = "Zorro", Breed = "Unknown" });
foreach (var item in list)
Console.WriteLine(item.Speek());
list = ReCalculateDOB(list);
foreach (var item in list)
Console.WriteLine(item.Speek());
}
你想重新计算所有哺乳动物的生日。上面的实现看起来像这样:
internal interface Mammal
{
string Speek();
}
internal class Person : Mammal
{
public string Name { get; set; }
public DateTime DOB { get; set; }
public string Speek()
{
return "My DOB is: " + DOB.ToString() ;
}
}
internal class Dog : Mammal
{
public string Name { get; set; }
public string Breed { get; set; }
public string Speek()
{
return "Woff!";
}
}
基本上你需要做的是使用Relfection,它是一种机制,用于检查类型并获取类型属性以及运行时类似的其他内容。这是一个关于如何为每个获得DOB的哺乳动物的上述DOB添加10天的示例。
static List<Mammal> ReCalculateDOB(List<Mammal> list)
{
foreach (var item in list)
{
var properties = item.GetType().GetProperties();
foreach (var property in properties)
{
if (property.PropertyType == typeof(DateTime))
property.SetValue(item, ((DateTime)property.GetValue(item, null)).AddDays(10), null);
}
}
return list;
}
请记住,使用反射可能很慢,而且通常很慢。
但是,上面会打印出来:
My DOB is: 2010-03-22 09:18:12
My DOB is: 2010-03-22 09:18:12
My DOB is: 2010-03-22 09:18:12
My DOB is: 2010-03-22 09:18:12
Woff!
Woff!
Woff!
My DOB is: 2010-04-01 09:18:12
My DOB is: 2010-04-01 09:18:12
My DOB is: 2010-04-01 09:18:12
My DOB is: 2010-04-01 09:18:12
Woff!
Woff!
Woff!
答案 1 :(得分:12)
它被称为反射。
var t = this;
var props = t.GetType().GetProperties();
foreach (var prop in props)
{
if (prop.PropertyType == typeof(DateTime))
{
//do stuff like prop.SetValue(t, DateTime.Now, null);
}
}
答案 2 :(得分:3)
class HasDateTimes
{
public DateTime Foo { get; set; }
public string NotWanted { get; set; }
public DateTime Bar { get { return DateTime.MinValue; } }
}
static void Main(string[] args)
{
foreach (var propertyInfo in
from p in typeof(HasDateTimes).GetProperties()
where Equals(p.PropertyType, typeof(DateTime)) select p)
{
Console.WriteLine(propertyInfo.Name);
}
}
答案 3 :(得分:1)
查找反思但基本上你这样做
obj.GetType()。GetProperties(.. Instance | ..Public),你得到了一个定义属性的列表..检查属性的值类型,并将其与typeof(DateTime)进行比较。
答案 4 :(得分:0)
对于非常快速的答案和指向该问题的指示,如果您有PowerShell可用(Vista / Windows 7,Windows 2008已安装它),您可以启动控制台和DateTime,例如做
Get-Date | Get-Member
其中将列出DateTime实例的成员。您还可以查看静态成员:
Get-Date | Get-Member -Static
答案 5 :(得分:0)
如果您担心反射对性能的影响,您可能会对Fasterflect感兴趣,这是一个可以更轻松,更快速地查询和访问成员的库。
对于instace,可以使用Fasterflect重写MaxGuernseyIII的代码:
var query = from property in typeof(HasDateTimes).Properties()
where property.Type() == typeof(DateTime)
select p;
Array.ForEach( query.ToArray(), p => Console.WriteLine( p.Name ) );
Fasterflect使用轻量级代码生成来更快地访问(如果您直接缓存和调用生成的委托,则速度提高2-5倍,或者接近原生速度)。查询成员通常更容易,更方便,但不是更快。请注意,这些数字不包括JIT编译生成代码的重要初始开销,因此只有重复访问才能看到性能增益。
免责声明:我是该项目的撰稿人。
答案 6 :(得分:0)
嘿,这个问题有点老了,但你可以用这个:
在类中的(选择所有值) - 设置值将在没有强制转换的情况下运行,仅用于选择:
(from property in this.GetType().GetProperties()
where property.PropertyType == typeof(DateTime)
select property.GetValue(this)).Cast<DateTime>()
课外的将是:
var instance = new MyClass();
var times = (from property in instance.GetType().GetProperties()
where property.PropertyType == typeof(DateTime)
select property.GetValue(instance)).Cast<DateTime>()
为获取最大日期时间值,我运行此
var lastChange = (from property in this.GetType().GetProperties()
where property.PropertyType == typeof(DateTime)
select property.GetValue(this)).Cast<DateTime>().Max();