2

わかりました、タイトルをひどく間違えたに違いありません。より多くのコード、より少ない言葉:

public class Manager<T> where T : Control, new()
{
    void Manage()
    {
        Do(t => IsVisible(t));
    }

    bool IsVisible(T t)
    {
        return t.Visible;
    }

    S Do<S>(Func<T, S> operation)
    {
        return operation(new T());
    }
}

コンパイラは満足していDoます。T型を簡単に推測できます。今私がこれを持っているとしましょう:

public static class Util
{
    static void Manage()
    {
        Do(t => IsVisible(t)); //wiggly line here
    }

    static bool IsVisible<T>(T t) where T : Control
    {
        return t.Visible;
    }

    static S Do<S, T>(Func<T, S> operation) where T : Control, new()
    {
        return operation(new T());
    }
}

コンパイラは、型を明示的に型付けする必要があります。これが私が思うことです:

最初のクラスでは、オーバーロードがあり、クラス全体で知られているメソッドTから簡単に推測できました。大したことではありません。しかし、2 番目のケースでは、メソッドの一般的な制約として指定されているため、推測するのが難しい場合があります。Ok。IsVisibleTTManagerT

しかし、これもうまくいきません:

public static class Util
{
    static void Manage()
    {
        Do(t => IsVisible(t)); //still wiggly line
    }

    static bool IsVisible(Control t)
    {
        return t.Visible;
    }

    static S Do<S, T>(Func<T, S> operation) where T : Control, new()
    {
        return operation(new T());
    }
}
  1. T最後のケースでコンパイラが推論しないのはなぜですか?

  2. さらに重要なことに、最後のケースは最初のケースとどのように違うのでしょうか? 最初のケースでは、コンパイラはメソッドからそれを推測し、最後にメソッドですぐに利用できるように、を含むクラスにIsVisible何があるかを確認する必要があります。したがって、3 番目のケースは最初のケースよりも簡単だと思います。TIsVisibleIsVisible

4

1 に答える 1

4

(最初のケース)

コンパイラは Do に満足しています。T 型を簡単に推測できます。

それはまったく推論Tしていません。Tクラスの型パラメーターです。

public class Manager<T> where T : Control, new()

(2 番目のケース)

コンパイラは、型を明示的に型付けする必要があります。

管理コードで次のことを意味していると思います。

Do(t => IsVisible(t))

そして、そうです。の型はここにあるべきだと思いますか? Tコンパイラがそれをどのように推測すると思いますか?

(方法が である 3 番目のケースIsVisible(Control t))

最後のケースでコンパイラが T を推論しないのはなぜですか?

パラメータだけではできません。ラムダ式の本体が機能するすべての型が機能することを期待しているように聞こえます...そして型推論は単にそのようには機能しません。ただし、コンパイラに十分な情報を簡単に提供できます。

 Do((Control t) => IsVisible(t)); 

さらに重要なことに、最後のケースは最初のケースとどのように違うのでしょうか?

最初のケースでは、メソッドTの型パラメーターではありません。Doコンパイラは、ラムダ式の戻り値の型から推論できることのみを必要とします。はすでに「既知」であるため、 のS推論を実行する必要はありません。T(これはまだジェネリックですが、そのメソッド call に対して推論する必要があるものではありません。) の型は、最初にTのインスタンスを構築するときに指定する必要があるManagerため、その決定を効果的に動かしています。

型推論の詳細については、C# 4 仕様のセクション 7.5.2 (または C# 3 または C# 5 仕様の同等のセクション) を参照してください。ただし、最初に濃いコーヒーをお勧めします:)

于 2012-11-04T13:48:27.383 に答える