tags:

views:

302

answers:

6

Got to do a quick job in C# which I am a complete noob. I need to adjust the datetime of a bunch of objects. I'd like to loop through the properties of the class and if the type is dateTime adjust accordingly. Is there any kind of 'describe type' built in goodness I can use?

+1  A: 

look up reflection but basicly you do this

obj.GetType().GetProperties(..Instance | ..Public) and you got a list of the properties defined.. check the value type of the property and compare it to typeof(DateTime).

Petoj
+6  A: 

It's called Reflection.

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);

    }
}
Axarydax
Much appreciated. Will look into reflection.
Chin
+2  A: 
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);
  }
}
+1 for linq solution
Axarydax
Ohh I didn't think of LINQ this time :)
Filip Ekberg
+3  A: 

You can use reflection for this.

Your scenario might look somewhat like this:

    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());
    }

Where you want to re-calculate the Birthdays of all Mammals. And the Implementations of the above are looking like this:

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!";
    }
}

So basicly what you need to do is to use Relfection, which is a mechanizm to check types and get the types properties and other things like that in run time. Here is an example on how you add 10 days to the above DOB's for each Mammal that got a DOB.

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;
}

Just remember that using reflection can be slow, and it is slow generally.

However, the Above will print this:

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!
Filip Ekberg
Wow, already marked an answer as correct. But your help has saved the day - cheers
Chin
A: 

For very quick answers and pointers to that question, and if you have PowerShell available (Vista / Windows 7, Windows 2008 already got it installed) you can just fire up the console and for DateTime e.g. do

Get-Date | Get-Member

Which will list you the members of a DateTime instance. You can also look at the static members:

Get-Date | Get-Member -Static
flq
A: 

If you are concerned about the performance impact of reflection you might be interested in Fasterflect, a library to make querying and accessing members easier and faster.

For instace, MaxGuernseyIII's code might be rewritten using Fasterflect like this:

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 uses light-weight code generation to make accesses faster (by a factor of 2-5 times, or with near-native speeds if you cache and invoke the generated delegates directly). Querying for members is generally easier and more convenient but not any faster. Note that these numbers do not include the significant initial overhead of JIT-compiling the generated code, so performance gains only become visible for repeated accesses.

Disclaimer: I am a contributor to the project.

Morten Mertner