Question about generic methods

  • Thread starter Thread starter Jeff Johnson
  • Start date Start date
J

Jeff Johnson

I've never written a generic method, and I've never looked into them too
closely. Now I'm reading a C# book and a generic method showed up in a code
sample which got me to thinking about them. Here's the method:

private static void Print<T>(IEnumerable<T> items)
{
foreach (T item in items)
{
Console.WriteLine(item);
}
}

Pretty simple stuff. Now, here's my question: in order to take a generic
parameter, does the method itself HAVE to be declared generic? In other
words, couldn't it just be

private static void Print(IEnumerable<T> items)

?

If the <T> is required after the method name, why? Is it just a case of
"because that's what the C# designers decided" or is there a deeper reason?
 
I've never written a generic method, and I've never looked into them too
closely. Now I'm reading a C# book and a generic method showed up in a code
sample which got me to thinking about them. Here's the method:

private static void Print<T>(IEnumerable<T> items)
{
foreach (T item in items)
{
Console.WriteLine(item);
}
}

Pretty simple stuff. Now, here's my question: in order to take a generic
parameter, does the method itself HAVE to be declared generic? In other
words, couldn't it just be

private static void Print(IEnumerable<T> items)

?

If the <T> is required after the method name, why? Is it just a case of
"because that's what the C# designers decided" or is there a deeper reason?

<T> need to either be either on the method or on the class.

Trying to infer it from the method signature may be possible, but
it seems rather messy to me.

Arne
 
<T> need to either be either on the method or on the class.

Trying to infer it from the method signature may be possible, but
it seems rather messy to me.

Example showing variations:

using System;

namespace E
{
public class Foo
{
public void Test1<T>()
{
Console.WriteLine(typeof(T).FullName);
}
public static void Test2<T>()
{
Console.WriteLine(typeof(T).FullName);
}
}
public class Bar<T>
{
public void Test1()
{
Console.WriteLine(typeof(T).FullName);
}
public static void Test2()
{
Console.WriteLine(typeof(T).FullName);
}
}
public class Program
{
public static void Main(string[] args)
{
Foo foo = new Foo();
foo.Test1<int>();
Foo.Test2<int>();
Bar<int> bar = new Bar<int>();
bar.Test1();
Bar<int>.Test2();
Console.ReadKey();
}
}
}

Arne
 
And there's the trick: I have NEVER (that I can recall) seen a method called
this way. I didn't even know it was possible.

It certainly is.

Note that T is often inferred from actual arguments:

using System;

namespace E
{
public class Foo
{
public void Test1<T>()
{
Console.WriteLine(typeof(T).FullName);
}
public static void Test2<T>()
{
Console.WriteLine(typeof(T).FullName);
}
public void Test3<T>(T o)
{
Console.WriteLine(typeof(T).FullName);
}
public static void Test4<T>(T o)
{
Console.WriteLine(typeof(T).FullName);
}
}
public class Bar<T>
{
public void Test1()
{
Console.WriteLine(typeof(T).FullName);
}
public static void Test2()
{
Console.WriteLine(typeof(T).FullName);
}
public void Test3(T o)
{
Console.WriteLine(typeof(T).FullName);
}
public static void Test4(T o)
{
Console.WriteLine(typeof(T).FullName);
}
}
public class Program
{
public static void Main(string[] args)
{
Foo foo = new Foo();
foo.Test1<int>();
Foo.Test2<int>();
foo.Test3(123);
Foo.Test4(123);
Bar<int> bar = new Bar<int>();
bar.Test1();
Bar<int>.Test2();
bar.Test3(123);
Bar<int>.Test4(123); // <---- deviation
Console.ReadKey();
}
}
}

Arne
 
Back
Top