views:

127

answers:

5

I'm writing a couple of classes that all have generic type arguments, but I need to overload the classes because I need a different number of arguments in different scenarios. Basically, I have

 public class MyGenericClass<T> { ... }
 public class MyGenericClass<T, K> { ... }
 public class MyGenericClass<T, K, L> { ... }
 // it could go on forever, but it won't...

I want them all in the same namespace, but in one source file per class. What should I name the files? Is there a best practice?

+2  A: 

I've seen people use

MyGenericClass`1, MyGenericClass`2 or MyGenericClass`3

(the number is the number of Generic Parameters).

I think that's what you get as a TypeName when you call .ToString on the class.

Michael Stum
Also XML docs use this, and IOC definitions
Chris S
The `.ToString()` argument is by far the best I've seen in discussions about this so far. Unless something unravelling comes up in the next day or so, this is probably what I'll do.
Tomas Lycken
Agreed. This is what comes up in the code coverage results as well.
Peter LaComb Jr.
Marked this as my "correct" answer now, since no more compelling arguments have come up. I think the fact that the file is named the same way as `.ToString()` works really does make this the best way to do it. (The fact that `.ToString()` uses characters that may not be valid everywhere is a different discussion...)
Tomas Lycken
@Tomas I was also suspicious about the backtick at first, but unlike the standard apostrophe ' it should be a valid character pretty much everywhere.
Michael Stum
+1  A: 

I think you won't find much dogma in the C# community favoring separate files for each variant of a generic class with the same name; I prefer to just use one for the case you're describing, though I could see a case for what you're proposing if the code is necessarily complex/long for each variation. Generally I'd just use the name of the class in question as the filename.

If I were going to separate the variants into separate files, I could see using Michael's solution, though that would be a bit painful for those of us who use Unix-style tools on the command line in, for example, Cygwin or AndLinux. I'd probably use an underscore or no punctuation. Or something like 1P, 2P, 3P as the suffix.

JasonTrue
+1  A: 

I'd put them all in the same file unless they are large (which usually they won't be, except the one with the most Ts).

There isn't really a best practice for naming classes besides what you find in the .NET framework guidelines, as it's part of the creative side of programming, and unfortunately the SSCLI only goes back to 2.0 so you can't find much help there.

Chris S
A: 

I usually use Classname.1.cs, Classname.2.cs, etc... where the number is the number of generic arguments, similar to the `1 notation used in the framework documentation (and in XML documentation in your sourcecode). Sometimes you also have a class with no generic arguments (similar to ICollection and ICollection<T> in the framework), and the filename would be just the class name, as expected. In contrast to using a backtick, this has the advantage that you won't have any invalid characters in the filename. Not all filesystems, versioning systems, operating systems allow a backtick character in the name.

Virtlink
+1  A: 

When this situation arises I adopt the same convention that is used in the XML documentation comments for C# generics, which is to use { and } instead of < and > because angle brackets aren't friendly in either XML or file names but curly ones are. So something like:

MyClass{T}.cs

MyClass{T,K}.cs

If you really have very many parameters though, this can get somewhat unwieldy as a naming scheme, so then I'd tend to adopt the CLR convention of backtick followed by parameter count, e.g.

MyClass`1.cs

MyClass`2.cs

Or mix and match the two schemes as fits the situation.

Greg Beech