views:

278

answers:

3

I want to create a class which implements IEnumerable<T> but, using reflection, generates T's and returns them via IEnumerable<T>, where T' is a entirely constructed subclass of T with some properties hidden and others read-only.

Okay., that might not be very clear. Let me explain this via the medium of code - I'd like to have a class CollectionView<T> as follows:-

public class CollectionView<T> : IEnumerable<T> {
  public CollectionView(IEnumerable<T> inputCollection, 
    List<string> hiddenProperties, List<string> readonlyProperties) {
    // ...
  }

  // IEnumerable<T> implementation which returns a collection of T' where T':T.
}

...

public class SomeObject {
  public A { get; set; }
  public B { get; set; }
  public C { get; set; }
}

...

var hiddenProperties   = new List<string>(new[] { "A" });
var readOnlyProperties = new List<string>(new[] { "C" });

IEnumerable<SomeObject> someObjects = CollectionView<SomeObject>(hiddenProperties,
  readOnlyProperties);

...

dataGridView1.DataSource = someObjects;

(When displayed in dataGridView1 shows columns B and C and C has an underlying store which is read-only)

Is this possible/desirable or have I completely lost my mind/does this question demonstrate my deep inadequacy as a programmer?

I want to do this so I can manipulate a collection that is to be passed into a DataGridView, without having to directly manipulate the DataGridView to hide columns/make columns read-only. So no 'oh just use dataGridView1.Columns.Remove(blah) / dataGridView1.Columns[blah].ReadOnly = true' answers please!!

Help!

+1  A: 

Castle.DynamicProxy will help you accomplish this. What you would do is create an interceptor that inherits T. You would store the collection of hidden and read-only properties. When a getter or setter is called, the interceptor would check to see if the property exists in either collection and then take appropriate action.

However, I know not how you would hide a property. You cannot change the access modifier of a base class in a derived class. You MAY be able to use the new keyword, but I know not how to do that with Castle.DynamicProxy.

Gilligan
A: 

You just can't hide properties, even by creating subclassed proxies. You could at least construct a different type dynamically, which holds good properties, but it would not be a T.

But returning an object list could be sufficient if you just need to use databinding.

Romain Verdier
A: 

I decided to take a different approach to this problem, I really wasn't seeing the wood for the trees! I decided to create an extension method which converts my IEnumerable to a data table which can then be passed around as required:-

public static DataTable ToDataTable<T>(this IEnumerable<T> collection)
{
    DataTable ret = new DataTable();

    Type type = typeof(T);

    foreach (PropertyInfo propertyInfo in type.GetProperties())
    {
        // Ignore indexed properties.
        if (propertyInfo.GetIndexParameters().Length > 0) continue;
        ret.Columns.Add(propertyInfo.Name);
    }

    foreach (T data in collection)
    {
        DataRow row = ret.NewRow();
        foreach (PropertyInfo propertyInfo in type.GetProperties())
        {
            // Ignore indexed properties.
            if (propertyInfo.GetIndexParameters().Length > 0) continue;

            row[propertyInfo.Name] = propertyInfo.GetValue(data, null);
        }

        ret.Rows.Add(row);
    }

    return ret;
}
kronoz