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

StackOverflow https://stackoverflow.com/questions/1023345

  •  06-07-2019
  •  | 
  •  

Вопрос

Я просматриваю главу 9 книги Джона Скита «CSharp in Depth», раздел, в котором объясняются улучшения вывода типов в версии 3.0.

На стр. 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.
    }
Это было полезно?

Решение

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

Другие советы

На моем компьютере установлена ​​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.

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

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

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

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

  • IDE:Визуальная Студия 2008
  • Платформа .NET:вы нацелены на .NET 2.0
  • СЛР:вы ориентируетесь на 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.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top