Начну с того, что я - разработчик Java, учусь программировать на C #. Поэтому я делаю сравнения того, что я знаю, с тем, что я изучаю.
Я играю с дженериками C # уже несколько часов, и мне удалось воспроизвести те же вещи, которые я знаю в Java на C #, за исключением нескольких примеров, использующих ковариацию и контравариантность. Книга, которую я читаю, не очень хороша в предмете. Я, конечно, буду искать больше информации в Интернете, но пока я делаю это, возможно, вы поможете мне найти реализацию C # для следующего кода Java.
Пример стоит тысячи слов, и я надеялся, что, посмотрев хороший пример кода, я смогу быстрее усвоить это.
ковариации
В Java я могу сделать что-то вроде этого:
public static double sum(List<? extends Number> numbers) {
double summation = 0.0;
for(Number number : numbers){
summation += number.doubleValue();
}
return summation;
}
Я могу использовать этот код следующим образом:
List<Integer> myInts = asList(1,2,3,4,5);
List<Double> myDoubles = asList(3.14, 5.5, 78.9);
List<Long> myLongs = asList(1L, 2L, 3L);
double result = 0.0;
result = sum(myInts);
result = sum(myDoubles)
result = sum(myLongs);
Теперь я обнаружил, что C # поддерживает ковариацию / контравариантность только на интерфейсах и до тех пор, пока они явно объявлены для этого (out / in). Я думаю, что я не смог воспроизвести этот случай, потому что я не смог найти общего предка всех чисел, но я считаю, что я мог бы использовать IEnumerable, чтобы реализовать такую вещь, если существует общий предок. Поскольку IEnumerable является ковариантным типом. Верно?
Есть мысли о том, как реализовать список выше? Просто укажи мне правильное направление. Есть ли общий предок всех числовых типов?
контрвариация
Пример контравариантности, который я пробовал, был следующим. В Java я могу сделать это, чтобы скопировать один список в другой.
public static void copy(List<? extends Number> source, List<? super Number> destiny){
for(Number number : source) {
destiny.add(number);
}
}
Тогда я мог бы использовать его с контравариантными типами следующим образом:
List<Object> anything = new ArrayList<Object>();
List<Integer> myInts = asList(1,2,3,4,5);
copy(myInts, anything);
Моя основная проблема при попытке реализовать это в C # состоит в том, что я не могу найти интерфейс, который был бы одновременно ковариантным и контравариантным, как это происходит со списком в моем примере выше. Может быть, это можно сделать с помощью двух разных интерфейсов в C #.
Есть мысли о том, как это реализовать?
Большое спасибо всем за ответы, которые вы можете внести. Я почти уверен, что многому научусь из любого примера, который вы можете предоставить.