Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about indexers and/or generics

how is it possible to know whether an object implements an indexer?, I need to share a logic for a DataRow and a IDataReader, but they don't share any interface.

I tried also with generics but don't know what restriction should I put on the where clause.

public class Indexer {
    // myObject should be a DataRow or a IDataReader
    private object myObject;
    public object MyObject {
        get { return myObject; }
        set { myObject = value; }
    }
    // won't compile, myObject has no indexer
    public object this[int index] {
        get { return myObject[index]; }
        set { myObject[index] = value; }
    }
    public Indexer(object myObject) {
        this.myObject = myObject;
    }
}

public class Caller {
    void Call() {
        DataRow row = null;
        IDataReader reader = null;
        var ind1 = new Indexer(row);
        var ind2 = new Indexer(reader);
        var val1 = ind1[0];
        var val2 = ind1[0];
    }
}
like image 454
Jhonny D. Cano -Leftware- Avatar asked Dec 06 '25 05:12

Jhonny D. Cano -Leftware-


1 Answers

You'd need to declare an interface with an indexer property, use that interface as the constraint, and the type argument class would need to implement that interface in order to satisfy the constraint.

As you don't control the classes you want to use, that wouldn't work.

An alternative is to make the Indexer class take the get/set operations as separate parameters:

public class Indexer {

    private Func<int, object> getter;        
    private Action<int, object> setter;

    public object this[int index] 
    {
        get { return getter(index); }
        set { setter(index, value); }
    }

    public Indexer(Func<int, object> g, Action<int, object> s) 
    {
        getter = g;
        setter = s;
    }
}

public static class IndexerExtensions
{
    public static Indexer ToIndexer(this DataRow row)
    {
        return new Indexer(n => row[n], (n, v) => row[n] = v);
    }

    public static Indexer ToIndexer(this IDataReader row)
    {
        return new Indexer(n => row[n], (n, v) => row[n] = v);
    }
}

You could then do this:

DataRow row = null;
IDataReader reader = null;
var ind1 = row.ToIndexer();
var ind2 = reader.ToIndexer();
var val1 = ind1[0];
var val2 = ind1[0];
like image 136
Daniel Earwicker Avatar answered Dec 07 '25 18:12

Daniel Earwicker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!