Как написать функцию, чтобы взять любой объект с оператором индекса - PullRequest
0 голосов
/ 25 сентября 2011

Я думаю, что спрашивал об этом в контексте C ++ (не могу найти его в моей истории вопросов !!) в прошлом, и решение было использовать функцию шаблона.Как шаблон C ++ разрешается во время компиляции, он работает.Но для C # это не так.

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

    return table;
}

В настоящее время одним из применений является преобразование результата в OleDbReader в хеш-таблицу, но я ожидаю, что скоро потребуется больше типов источников.

Ответы [ 4 ]

2 голосов
/ 25 сентября 2011

Вы можете использовать интерфейс:

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

, и ваш метод будет показан ниже:

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

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

}

Простой источник:

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 
        }
    }
}

Простой потребитель это:

public class Consumer{

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

}
1 голос
/ 25 сентября 2011

Не могли бы вы добавить ограничение, чтобы указать, что параметр типа был IList?

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

    return table;
}

Свойство Item this[int index] не является оператором, оно является членом свойства содержащего типа. IList разоблачает это.

0 голосов
/ 29 сентября 2011

Нет универсальных ограничений типа для операторов в C # - это одно из ограничений универсальных в C #.

0 голосов
/ 25 сентября 2011

Если проверки во время выполнения достаточно хороши, вы можете использовать отражение в качестве одного из предложенных комментаторов:

if (typeof (T).GetProperties().Any(property => property.Name.Equals("Item")))
...