Почему следующий фрагмент кода должен быть проблемой для вывода типа C # 2.0? - PullRequest
1 голос
/ 21 июня 2009

Я в 9-й главе CSharp Jhon Skeet в разделе «Глубина», в разделе, где объясняются улучшения, связанные с выводом типов в версии 3.0

.

На Pg.247 есть фрагмент кода, который «не должен компилироваться с 2.0» - однако я не могу найти причину, почему он не должен. Попытался решить проблему с VS2008 C # Express Edition в проекте с целевым фреймворком как 2.0 - . Все три из приведенных ниже вызовов компилируются и выполняются слишком .

В

2.0 появилась возможность вывести правильный тип делегата.

new List<ThreadStart>().Add( delegate { Console.WriteLine("New Thread!"); } );   // works

Конечно, Джон не может ошибаться (;) 'Sql не работает' + об этом нет упоминания на странице с ошибками для книги.) Так что я подозреваю, что он все еще использует вывод типа 3.0 - Что я скучаю?

    delegate int MyDelegate(string s);
    delegate TOutput MyConverter<TInput, TOutput>(TInput input);
    static void MyParse(MyDelegate del)
    {
        Console.WriteLine(del("100"));
    }
    static void MyConvert<TInput, TOutput>(MyConverter<TInput, TOutput> del, TInput input)
    {
        Console.WriteLine(del(input));
    }

    // Jon's code snippet begin
    delegate T MyFunc<T>();
    static void WriteResult<T>(MyFunc<T> function)
    {
        Console.WriteLine(function());
    }
    // end

    static void Main(string[] args)
    {
        MyParse(delegate(string s)
            {
                return Int32.Parse(s);
            }
        );
        MyConvert(delegate(string s)
            {
                return Int32.Parse(s);
            },
            "100");
        WriteResult(delegate { return 5; });    // Jon: Shouldn't work.
    }

Ответы [ 4 ]

4 голосов
/ 21 июня 2009

На моем компьютере установлена ​​Visual Studio 2005, и я только что опробовал код, который вы опубликовали.

И MyConvert, и WriteResult не работают. Я получаю следующие ошибки:

The type arguments for method 'ConsoleApplication1.Program.MyConvert<TInput,TOutput>(ConsoleApplication1.Program.MyConverter<TInput,TOutput>, TInput)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

и

The type arguments for method 'ConsoleApplication1.Program.WriteResult<T>(ConsoleApplication1.Program.MyFunc<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
4 голосов
/ 21 июня 2009

Что делает параметр «target framework», так это отключать библиотеки и методы, которые были добавлены в более новые версии Framework. Большинство новых языковых функций не требуют специальной поддержки во время выполнения или новых библиотек. Поэтому, если вы используете их, вам нужен более новый компилятор, но ваше приложение все равно будет работать на 2.0.

3 голосов
/ 21 июня 2009

Здесь задействовано несколько разных версий:

  • IDE: Visual Studio 2008
  • .NET Framework: вы ориентируетесь на .NET 2.0
  • CLR: вы нацеливаетесь на 2.0 (игнорируя пакеты обновления:)
  • Используемый вами компилятор C #: Visual Studio 2008 всегда использует компилятор C # 3.0
  • Языковая версия, на которую ориентирован компилятор: по умолчанию 3.0

Чтобы вывести вывод из строя, не возвращаясь к компилятору версии 2.0, вам нужно заставить компилятор C # использовать версию 2 языка. Я не знаю, предоставляет ли это экспресс-выпуск Visual Studio, но вы можете использовать командную строку, чтобы увидеть это.

К сожалению - а это действительно странно - я теперь тоже не могу воспроизвести сложность таким образом.

Вот что я только что попробовал:

using System;

class Test
{
    public delegate T Function<T>();
    public static T Execute<T>(Function<T> function)
    {
        return function();
    }

    static void Main()
    {
        Execute(delegate { return 5; });
    }
}

Я ожидал, что компиляция с

csc /langversion:ISO-2 Test.cs

потерпит неудачу ... но это не так. Это терпит неудачу с реальным компилятором C # 2:

>c:\Windows\Microsoft.NET\Framework\v2.0.50727\csc Test.cs
Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.3053
for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.

Test.cs(14,9): error CS0411: The type arguments for method
        'Test.Execute<T>(Test.Function<T>)' cannot be
        inferred from the usage. Try specifying the type 
        arguments explicitly.
3 голосов
/ 21 июня 2009

У меня нет моей копии книги Джона, но он, вероятно, скоро будет!

В каком разделе это находится? Попробуйте поискать здесь: http://csharpindepth.com/Notes.aspx

РЕДАКТИРОВАТЬ: На самом деле, ориентация на версию фреймворка не имеет никакого отношения к версии компилятора. Таким образом, вы все еще используете C # 3.0. Компилятору просто нужно выяснить, какой IL сгенерировать, чтобы он работал на CLR 2.0, и поэтому он может выполнять столько операций вывода, сколько ему нравится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...