Generics has certainly opened up a few design opportunities for class library developers that weren’t there before. My gut feeling however is that there is more we could do so I’m going to expand upon my post on indexes in .NET BCL 3.0 collections and introduce the concept of member parameters.

The idea is that members such as properties, fields and even methods become valid parameters for generic types. It would work something like this.

  1 Customer customer = new Customer();
  2 customer.ID = "MDENN";
  3 customer.FirstName = "Mitch";
  4 customer.LastName = "Denny";
  5
  6 StringIndex<Customer, Customer.ID> customerIndex = new StringIndex<Customer, Customer.ID>();
  7 QueryResults<Customer> results = customerIndex.Query("MDENN");

You can see in the declaration for “customerIndex” that the second parameter for the type is actually a property and support syntax like the following in the Add method (where things are actually inserted into the index).

  1 public class StringIndex<EntityType, IndexProperty>
  2 {
  3 	public void Add(Customer entity)
  4 	{
  5 		string indexValue = IndexProperty(entity);
  6 		// Add entity to index with indexValue;
  7 	}
  8 }

You could achieve something similar by using generic delegate types but I think this syntax would be clearer in most situations – maybe its just a shortcut syntax. Obviously you would need to be able to apply constraints to the member parameters just like you can to type parameters, for example you’d probably constrain the StringIndex’s member parameter to being a string.

2 Responses to “Type Parameters? I want Member Parameters!”

  1. AlSki Says:

    Mitch,

    I think we might have just arrived at the same problem from very different starting and ending places.

    Have you considered using a Predicate<T>, this could change your code into

    List<Customer> customers = new StringIndex<Customer>();

    queryID = “MDENN”;

    List<Customer> results = customers.FindAll(new Predicate<Customer> queryID);

    private bool queryID(Customer cust)

    {

    return (cust.ID == queryID);

    }

    However this simple example leads into the problems of reentrant code when threading (see link), but you are 90% there now.

  2. Mitch Denny Says:

    That wouldn’t work – that would require you to execute the Predicate against each item in the list everytime you did a search. What I am talking about is an index which is much faster (orders of magnitude). Predicate is the equivalent of an index scan.

    Having said that, if I defined the StringIndex thusly:

    public class StringIndex<T>

    {

    public StringIndex(Extractor<T> extractor) { }

    }

    Then I could hold onto the extractor and use it in the Add method. That’s what I meant when I said you could do it with delegates already.


Leave a Reply