views:

56

answers:

2

How will I know if an object instance is a property or a sub property of another object instance?

for example I have this class structure:

public class Car
{
      public Manufacturer Manufacturer {get;set;}
}

public class Manufacturer
{
      public List<Supplier> {get;set;}
}

public class Supplier
{
      string SupplierName {get;set;}
}

And I only have two instances, the Car and the SupplierName; Using PropertyInfo in Reflection, How can I Implement a method such as

bool IsPropertyOrSubPropertyOf(object ObjectInstance, object TargetObejectInstance)

used as

IsPropertyOrSubPropertyOf(SupplierNameInstance, CarInstance)

this method will return true if the CarInstance's Property Manufacturer has a Supplier that has a SupplierName SupplierNameInstance

+2  A: 

You shouldn't need to use reflection for the particular example you describe:

bool IsPropertyOrSubPropertyOf(Supplier supplierInstance, Car carInstance)
{
    return carInstance.Manufacturer.Suppliers.Contains(supplierInstance);
}

(By the way, you missed out the name of the List<Supplier> property in your Manufacturer class. I've assumed that it's actually called Suppliers in my code above.)

LukeH
Yeah it's Suppliers. Assuming that the signature of the method is bool IsPropertyOrSubPropertyOf(object ObjectInstance, object TargetObejectInstance)the method should not be specific to a Supplier and a Car. I want it to be generic in a way that you can pass any instance of any object. If I do IsPropertyOrSubPropertyOf(supplierInstance, ManufacturerInstance) it should still return true if the Supplier instance is a part of the manufacturer's property.
Lawrence A. Contreras
+1  A: 

Does this do what your looking for? Sorry if its not the cleanest - you will probably want to add some null checks in there aswell.

    private bool IsPropertyOrSubPropertyOf(Object Owner, Object LookFor)
 {

  if (Owner.Equals(LookFor))
  {
   // is it a property if they are the same?
   // may need a enum rather than bool
   return true;
  }

  PropertyInfo[] Properties = Owner.GetType().GetProperties();

  foreach (PropertyInfo pInfo in Properties)
  {
   var Value = pInfo.GetValue(Owner, null);

   if (typeof(IEnumerable).IsAssignableFrom(Value.GetType()))
   {
    // Becomes more complicated if it can be a collection of collections
    foreach (Object O in (IEnumerable)Value)
    {
     if (IsPropertyOrSubPropertyOf(O, LookFor))
      return true;
    }
   }
   else
   {
    if (IsPropertyOrSubPropertyOf(Value, LookFor))
    {
     return true;
    }
   }

  }
  return false;
 }


Edit: I just noticed that if LookFor is IEnumerable then you may end up with an issue, will leave that to you to sort out ;)

Courtney de Lautour
I think LookFor, in my case, will not be an IEnumerable. I'll try this logic if it will work, and I strongly think it will.
Lawrence A. Contreras
It worked, I just added a depth parameter to indicate how deep it will dig the sub properties because it seems to be a never ending loop without that. And ofcourse the null checks and some exception handling. Thanks very much.
Lawrence A. Contreras
it's a little bit lag for my application but I think, using the new Task Parallel library(TPL) of Microsoft will help.
Lawrence A. Contreras
Any tips on optimizing this method?
Lawrence A. Contreras
Unfortunately I don't know any optimization offhand - reflection is pretty slow in general. I wouldn't have thought you would have any infinite loops unless you have a looping property 'O1.Prop = O2; O2.Prop = O1;' you could probably pass a stack of objects which have already been compared and make sure that the 'Value' you just got hasn't occurred before.
Courtney de Lautour