-1

I think I have asked this in the context of C++ (Can't find it in my question history!!) in the past and the solution was to use a template function. As C++ template resolve at compile time, it works. But for C#, it doesn't.

public Hashtable ConvertToHashtable<T>(T source) where T has an index operator
{
    Hashtable table = new Hashtable();
    table["apple"] = source["apple"];

    return table;
}

One usage at the moment is to convert the result in OleDbReader to hashtable, but I am forseeing the need for more source types soon.

Amittai Shapira
  • 3,749
  • 1
  • 30
  • 54
Jake
  • 11,273
  • 21
  • 90
  • 147

4 Answers4

2

You can use an interface:

public interface IIndexable<T> {
    T this[int index] { get; set; }
    T this[string key] { get; set; }
}

and your method will be seen as below:

public Hashtable ConvertToHashtable<T>(T source) 
    where T : IIndexable<T> {

    Hashtable table = new Hashtable();
    table["apple"] = source["apple"];
    return table;

}

A simple source is:

public class Source : IIndexable<Source> {

    public Source this[int index] {
        get {
            // TODO: Implement 
        }
        set {
            // TODO: Implement 
        }
    }

    public Source this[string key] {
        get {
            // TODO: Implement 
        }
        set {
            // TODO: Implement 
        }
    }
}

A simple consumer is:

public class Consumer{

    public void Test(){
        var source = new Source();
        var hashtable = ConvertToHashtable(source);
        // you haven't to write: var hashtable = ConvertToHashtable<Source>(source);
    }

}
amiry jd
  • 27,021
  • 30
  • 116
  • 215
1

Could you add a constraint to specify that the type parameter was an IList?

public Hashtable ConvertToHashtable<T>(T source) where T : IList
{
    Hashtable table = new Hashtable();
    table["apple"] = source["apple"];

    return table;
}

The Item property this[int index] is not an operator, its a property member of the containing type. IList exposes this.

Matthew Abbott
  • 60,571
  • 9
  • 104
  • 129
0

If runtime checks are good enough, you could use reflection as one of the commentator suggested as follows:

if (typeof (T).GetProperties().Any(property => property.Name.Equals("Item")))
Amittai Shapira
  • 3,749
  • 1
  • 30
  • 54
0

There are no generic type constraints for operators in C# - it is one of the limitations of generics in C#.

Oded
  • 489,969
  • 99
  • 883
  • 1,009