3

非ジェネリック デリゲート宣言は次のように行われます。

delegate void Print(int arg);

ここvoidで、 は戻り値の型で、int引数の型です。

一般的なデリゲート宣言は次のとおりです。

delegate void Print<T> (T arg);

ここで、voidは再び戻り値の型でT、括弧内はジェネリック引数の型です。

戻り値の型と引数の型はわかっているのに、角かっこで追加の型が必要なのはなぜでしょPrint<T>うか。それは何を意味しますか?

よろしくお願いします。

4

4 に答える 4

6

<T>inは、Print<T>ジェネリック メソッドを作成しようとしていることをコンパイラに伝えるために必要です。そうしないとT、型パラメーターではなく、何らかの型であると見なされる可能性があります。直感的に作者の意図を推測できますが、コンパイラはそれについてより文字通りです。

于 2012-08-22T05:15:51.713 に答える
4

これは、ジェネリック メソッドを扱っていることをコンパイラに伝えます。

あなたが示唆しているのは、コンパイラがこの宣言が一般的であると推測するということです:

delegate void Print (T arg)

の存在下で何が起こるか

class T { }

?

于 2012-08-22T05:16:11.997 に答える
4

括弧内にその「追加の型」がなければ、C# コンパイラはT、パラメーター リストでジェネリック型として扱うべきか、それとも名前が実際Tに inのような型を期待するべきかを知る方法がありませんclass T {}

于 2012-08-22T05:17:23.960 に答える
2

サイドノートの並べ替え:ジェネリッククラス内で完全に有効な構文であり、「このデリゲートはクラス全体delegate void Print(T arg);と同じ型を取る」ことを意味します(Tがクラスのジェネリック型であると仮定します)。arg

delegate void Print2<T>(T arg);同じクラスで宣言することもできます。意味 (およびコミラーが警告します) は異なります: デリゲートは任意の型を引数として使用し、クラスで使用されるものとTは無関係です(コードでそうするのは良くなく、混乱を招くことに注意してください)。T

class GenericClass<T>
{
   delegate void Print(T arg); // T is the same as T in the class

   delegate void Print2<T>(T arg); // T is unrelated to T in the class.
}

関数を含む同様のコード:

using System;
class Program {
void Main()
{
  var x = new A<int>();
  // x.Print("abc");  - compile time error
  x.Print(1); // Print only accepts same Int32 type 

  x.Print2(1);     // Print2 can use as the same Int32 used for class
  x.Print2("abc"); // as well any other type like string.
}

public class A<T>
{
   public void Print(T arg)
   {
      Console.WriteLine("Print:{0} = {1}", arg.GetType().FullName, arg);
   }
   public void Print2<T>(T arg)
   {
Console.WriteLine("PRINT2:{0} = {1}", arg.GetType().FullName, arg);
   }
}
}
于 2012-08-22T06:16:51.427 に答える