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!
-
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.From Gilligan -
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.
From Romain Verdier -
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; }
From kronoz
0 comments:
Post a Comment