Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extension Methods for Indexers, would they be good? [closed]

Tags:

Extension Methods for Indexers, would they be good ?

I was playing around with some code that re-hydrates POCO's.

The code iterates around rows returned from a SqlDataReader and and uses reflection to assign properties from column values. Down my call stack I had a code a line like this :-

poco.Set("Surname", "Smith"); // uses extension method ...

The Set method was written as an extension method.

It would be great to have been able to write code like this

poco["Surname"] = "Smith";  // extension methods for indexers ?

ie I wanted to write an extension method for indexer

Are there good reason why .Net does not have extension methods for indexers? Do other people have other good uses for extension method indexers ?

as an aside ... If we could write extension methods for indexers then we could write code like this …

var poco = PocoFactory();  
    poco.Surname = “Smith”; // is this JavaScript ...
    poco[Surname] = “Smith” ; // … or is this c# or both

Some snippets from my code

/////////////////////////////////////////////
// Client calling code
IDab dab = DabFactory.Create( "Northwind" );
string sql = @"select * from Customers ";
var persons = dab.ExecuteReader<NorthwindCustomer>(sql);
if (dab != null{
   Assert.That(persons[0].CustomerID , Is.EqualTo("ALFKI"));}
/////////////////////////////////////////////
List<T> IDab.ExecuteReader<T>(string commandText) 
{
    List<T> pocos = new List<T>();
    // setup connection
    SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
    while (reader.Read())
    {
            Dictionary<string, int> colMappings = null ;
            if (colMappings == null){
                colMappings = reader.GetSqlDataReaderColumnMappings();}
            T poco = new T();
            poco.DbToMem<T>(reader, colMappings);
            pocos.Add(poco);
        }
    }
    // connection cleanup ...
    return pocos ;
}

// the set extension method signature
public static void Set<T>(this T thisClientObject, string thisPropertyName, object newValue) where T : class
like image 269
judek Avatar asked Mar 01 '09 15:03

judek


People also ask

Are extension methods good?

So if extension methods and extension properties are really static methods and properties. And static methods and properties and methods are not thread safe and therefore should be avoided then extension methods and extension properties are bad.

What is the main purpose of an extension method?

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, but they're called as if they were instance methods on the extended type.

Are extension methods thread safe?

No, in general this method is definitely not thread-safe in respect to its argument record .

Where do extension methods go?

An Extension Method should be in the same namespace as it is used or you need to import the namespace of the class by a using statement. You can give any name of for the class that has an Extension Method but the class should be static.


1 Answers

Indexers share a lot of commonality with properties (under the hood, an indexer is a property with an index), and extension properties don't exist. Agreed, there would be scenarios where they are handy.

Re the scenario presented - in some ways, this is quite like dynamic. Of course, if you declare an interface that has a string indexer, then your reader-code could use it directly - but it would be a lot of unnecessary work to implement this interface repeatedly!

Re the extension method; does this use regular reflection? You might want to look at tricks like HyperDescriptor, which might save a lot of CPU time if you are doing lots of this. Typical usage would then be:

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
while (reader.Read())
{
     T poco = new T();
     // abbreviated...
     (per prop)
        props[propName].SetValue(poco, cellValue);
}

You can optimise this further by looking at the returned columns first (once per grid, not per row), and only accessing matched columns...

Or alternatively, look at ORM tools; Expression can also be used to do data reading (I have a complete example of this somewhere on usenet, for DbLinq)

like image 192
Marc Gravell Avatar answered Oct 02 '22 14:10

Marc Gravell