Optimizing For Loop result?

I'm currently using this code to check if the DataReader has column existing:

public static class DataRecordExtensions
{
    public static bool HasColumn(this IDataRecord dr, string columnName)
    {
        for (int i=0; i < dr.FieldCount; i++)
        {
            if (dr.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
                return true;
        }
        return false;
    }
}

I reuse this code alot and so it continuously runs through the For loop.

Is there anyway I can optimize this? For example, if a column is not existing, then it means result is same for everything and I don't have to iterate through everything again. Same with if it is existing, I know that it is existing and no need to go through the loop again.

Thank you!

Jon Skeet
people
quotationmark

The main problem would be in the calling code... but you can avoid calling the method more than once in total, by changing your method to create and return a HashSet<string>:

public static class DataRecordExtensions
{
    public static ISet<string> GetFieldNames(this IDataRecord dr, StringComparer comparer)
    {
        var sequence = Enumerable.Range(0, dr.FieldCount)
                                 .Select(i => dr.GetName(i));
        return new HashSet<string>(sequence, comparer);
    }
}

You can then call that method with your first record, passing in StringComparer.InvariantCultureIgnoreCase as the comparer, and you'll get back an ISet<string> that you can cheaply test for whether it contains a particular field name.

The awkward part is potentially calling this just once. You might need something like:

ISet<string> fields = null;
while (reader.Read())
{
    var record = ...;
    if (fields == null)
    {
        fields = record.GetFieldNames(StringComparer.InvariantCultureIgnoreCase);
    }
    // Use fields and record here
}

You might also want to consider returning a Dictionary<string, int> instead of an ISet<string>, if you need the field number as well.

people

See more on this question at Stackoverflow