2009-11-14 5 views
2

Я попытался применить операторы на дженериков (для моего примера, умножение)C#/Fixing Операторы дженериков

public static List<TOutput> Conversion<TOutput>(List<TInput> input) 
    { 
     List<TOutput> outList = new List<TOutput>(); 
     foreach(TInput tinput in input) 
     { 
      double dbl = tinput *tinput; 
      outList.Add(dbl); 

     } 
     return outList; 

    } 

Любой обходной путь для ее фиксации?

+0

Я не могу увидеть, что ваша цель в этом коде, но я думаю, что если вы читаете главы в «C# в глубине» Джона Скита «Об общих, перечислимых и Linq», вы найдете все, что вам нужно, в том числе примеры, которые очень близки к тому, что я предполагаю, ваше намерение. best, – BillW

+0

@BillW - вы абсолютно правы! (косвенно). См. Сайт книги, http://csharpindepth.com/ViewChapterNotes.aspx?Chapter=3, примечание 3.6.2 - который указывает на ответ, уже принятый для этого вопроса ;-p –

ответ

5

Невозможно без отражения по типу. Существует некоторый код, который делает это доступным как part of MiscUtil.

+0

+1 для показа утилиты – user196546

+0

D ' о - я опоздал; -p –

1

Компилятор не позволит вам назначить двойной неизвестный тип:

outList.Add (дублированный);

Для всего, что он знает, вы можете попытаться присвоить dbl типу FluxCapacitor. Ваш код пытается выполнить две несовместимые вещи: вернуть список общего (неизвестного) типа и 2) заставить этот тип быть двойным. Это не имеет смысла, поэтому у вас возникают трудности. Вы можете использовать отражение (как указал Поркс с отличной ссылкой), чтобы решить эту проблему динамически, но вам действительно нужно спросить себя: почему вы пытаетесь присвоить номер с плавающей точкой классу, который имеет неизвестный тип? Вызывающий код может запрашивать результат List<bool>. Какой смысл было бы предпринять, чтобы попытаться назначить

double foo = 1.5; 
bool bar = foo; 

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

1

«MiscUtil» ответ (уже принято) будет моим первым выбором ;-p

Вы также могли бы рассмотреть LINQ в вызывающем:

var prodList = originalList.Select(x=>x*x).ToList(); 

Поскольку абонент знает типа (при условии его . не сам родовое, это должно работать

Просто для полноты, другой вариант здесь (в 4.0) является dynamic:

public static List<TOutput> Conversion<TOutput>(List<TInput> input) 
{ 
    List<TOutput> outList = new List<TOutput>(); 
    foreach(TInput tinput in input) 
    { 
     TOutput square = (dynamic)tinput * (dynamic)tinput; 
     outList.Add(square); 

    } 
    return outList; 
} 
1

Вы можете использовать кэшированную лямбду для выполнения ваших расчетов (и/или преобразования).

Это не требует DLR или динамическое ключевое слово, так что прекрасно использовать в C# 3,0

static class Squarer<T> 
{ 
    private static readonly Func<T, T> _square; 
    static Squarer() 
    { 
     ParameterExpression x = Expression.Parameter(typeof(T), "x"); 
     _square = Expression.Lambda<Func<T, T>>(
      Expression.Multiply(x, x), 
      x).Compile(); 
    } 

    public static T Square(T value) 
    { 
     return _square.Invoke(value); 
    } 
} 

Console.WriteLine(Squarer<double>.Square(1234.5678)); 
Console.WriteLine(Squarer<decimal>.Square(1234.5678m)); 
Console.WriteLine(Squarer<int>.Square(1234)); 
Смежные вопросы