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.
There are no generic type constraints for operators in C# - it is one of the limitations of generics in C#.
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);
}
}
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.
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")))