Question about generic methods

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?
 
A

Arne Vajhøj

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
 
A

Arne Vajhøj

<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
 
A

Arne Vajhøj

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top