2009-07-01 4 views
0

Я новичок в C# 3.0 var type. Здесь у меня есть вопрос об этом типе. Возьмите следующие простые коды в библиотеке в качестве примера:Вопрос о var type

public class MyClass { 
    public var Fn(var inValue) 
    { 
     if (inValue < 0) 
     { 
      return 1.0; 
     } 
     else 
     { 
      return inValue; 
     } 
    } 
} 

Я думаю, что этот параметр является анонимным. Если я передаю значение float, то Fn должен возвращать тип float. Если вводится двойной тип значения, будет ли Fn возвращать двойной тип? Как насчет типа целочисленного значения в качестве входного значения?

На самом деле, я хотел бы использовать var type с помощью этой функции/метода для получения различных типов возвращаемых данных с различными типами входных данных динамически. Я не уверен, правильно ли это использование или нет?

+0

Мои коды могут быть неправильными. Я прочитал несколько статей об использовании var в локальной области, но не в библиотеке как var type для общедоступных методов. Не уверен, так как у меня нет VS, чтобы проверить его. –

ответ

8

Вы не можете использовать var для возвращаемых значений или типов параметров (или полей). Вы можете только использовать его для локальных переменных.

Эрик Липперт имеет blog post about why you can't use it for fields. Я не уверен, есть ли аналогичный для возвращаемых значений и типов параметров. Типы параметров, конечно, не имеют большого смысла - откуда мог компилятор вывести тип? Какие методы вы пытаетесь вызвать по параметрам? (На самом деле это довольно много, что F # делает, но C# является более консервативным.)

Не забывайте, что var является строго статической типизации - это просто способ получить компилятор выводить статический тип для вас. Это все еще только один тип, точно так же, как если бы вы ввели это имя в код. (За исключением, конечно, с анонимными типами вы не сделать это, что одна мотивация для функции.)

EDIT: Для получения более подробной информации о var, вы можете скачать главу 8 C# Глубины бесплатно на Manning's site - это включает раздел на var. Очевидно, я надеюсь, то вы хотите, чтобы купить книгу, но нет никакого давления :)

EDIT: Для того, чтобы решить ваши фактические цели, вы можете почти реализовать все это с помощью универсального метода:

public class MyClass 
{ 
    public T Fn<T>(T inValue) where T : struct 
    { 
     Comparer<T> comparer = Comparer<T>.Default; 
     T zero = default(T); 
     if (comparer.Compare(inValue, zero) < 0) 
     { 
      // This is the tricky bit. 
      return 1.0; 
     } 
     else 
     { 
      return inValue; 
     } 
    } 
} 

Как показано в листинге, сложный бит разрабатывает то, что означает «1» для произвольного типа. Вы можете жестко закодировать набор значений, но это немного некрасиво:

public class MyClass 
{ 
    private static readonly Dictionary<Type, object> OneValues 
     = new Dictionary<Type, object> 
    { 
     { typeof(int), 1 }, 
     { typeof(long), 1L }, 
     { typeof(double), 1.0d }, 
     { typeof(float), 1.0f }, 
     { typeof(decimal), 1m }, 
    }; 

    public static T Fn<T>(T inValue) where T : struct 
    { 
     Comparer<T> comparer = Comparer<T>.Default; 
     T zero = default(T); 
     if (comparer.Compare(inValue, zero) < 0) 
     { 
      object one; 
      if (!OneValues.TryGetValue(typeof(T), out one)) 
      { 
       // Not sure of the best exception to use here 
       throw new ArgumentException 
        ("Unable to find appropriate 'one' value"); 
      } 
      return (T) one; 
     } 
     else 
     { 
      return inValue; 
     } 
    } 
} 

неприглядное - но это будет работать. Тогда вы можете написать:

double x = MyClass.Fn(3.5d); 
float y = MyClass.Fn(3.5f); 
int z = MyClass.Fn(2); 

и т.д.

+2

Ха, я бил тебя дважды сегодня вечером. Это не произойдет часто. Я буду ждать ваших улучшенных исправлений, хотя :) –

+0

Прошу прощения, я буду оценивать «превосходное редактирование», но +1 для вашего юмора тоже :) –

5

Вы не можете использовать var как возвращаемый тип для метода.

+0

слишком плохо, как я догадался. Не похоже на Ruby или Python. Все нормально. Благодаря! –

+1

@ Давид: это динамические языки. Если вам не нравится статическая типизация, вы не получите много удовольствия в C#. Хотя C# 4 вводит динамическую типизацию, но я бы использовал только то, что вам действительно нужно. C# создается вокруг статически типизированного. –

Смежные вопросы