Search code examples
c#genericstype-constraints

How do I get the type of the item in an old style collection?


What I am actually trying to do is write a function that allows me to change the selection in a DataGridView and I would like to write one function and use it for both rows and columns. Here is a simple example that deselects everything and selects a new row or column:

private void SelectNew<T>(T collection, int index) where T : IList
{
  ClearSelection();
  collection[index].Selected = true;
}

My problem is that this does not work because it cannot be derived that .Selected() is available because this is the non-generic IList.

Using

where T : IList<DataGridViewBand>

would be nice but since DataGridViewRowCollection (and -Column-) just derive from IList this doesn't work.

In C++ I would probably use the traits idiom. Is there a way to do that in C# or is there a more idiomatic way?


Solution

  • While it's theoretically possible to use reflection to do this; since your explicit goal is just to handle rows or columns the easiest option is to just create two overloads for the function:

    private void SelectNew(DataGridViewColumnCollection collection, int index)
    {
        ClearSelection();
        collection[index].Selected = true;
    }
    
    private void SelectNew(DataGridViewRowCollection collection, int index)
    {
        ClearSelection();
        collection[index].Selected = true;
    }
    

    If you tried to use reflection to do this it would work, but it would be slower, less readable, and has the danger of no compile time protection; people would be able to pass in other kinds of lists that didn't have a Selected property and it would compile and just fail at runtime.