How to name C# source files for generic classes
Asked Answered
L

5

43

I am trying to stick to general naming conventions such as those described in Design Guidelines for Developing Class Libraries. I put every type into its own source file (and partial classes will be split across several files as described in question Naming Conventions for Partial Class Files), using the name of the type as the file name.

Examples:

namespace Demo.Bla                         //  project
{
    enum FlowDirection { }                 //  in file FlowDirection.cs
    class LayoutManager { }                //  in file LayoutManager.cs
}

namespace Demo.Bla.LayoutControllers       //  folder LayoutControllers in project
{
    class StackPanelLayoutController { }   //  in file LayoutControllers/StackPanelLayoutController
}

But I am not sure I've come up with a clever way of naming source files which contain generic classes. Say that I have following classes, for instance:

namespace Demo.Bla.Collections             //  folder Collections
{
    class Map<T> { }                       //  in file Map.cs (obviously)
    class Bag { }                          //  in file Bag.cs (obviously)
    class Bag<T> : Bag { }                 //  also in file Bag.cs ???
}

Should I put the code of both the non-generic and the generic Bag classes into the same Bag.cs file? What are your habits?

Lucknow answered 24/6, 2010 at 8:8 Comment(4)
Possible dup : #2612139Gent
@Jehof: Related, but not a dup. This is a generic/non-generic question (and a naming convention question too).Kuibyshev
@Gent - Thank you for the pointer to question 2611639. It has interesting replies to the generic class naming issue.Lucknow
possible duplicate of Convention for Filenames of Generic ClassesAlexi
L
6

In the CoreFX GitHub repository, Microsoft is following the back-tick convention described in Matthias Jakobsson's answer:

enter image description here

So basically:

class ImmutableArray { }                      // ImmutableArray.cs
class ImmutableArray<T> { }                   // ImmutableArray`1.cs
...
class ImmutableDictionary<TKey, TValue> { }   // ImmutableDictionary`2.cs

And for classes defined inside other classes, the name is composed by the outer class followed by + and by the name of the inner class (Outer+Inner.cs):

partial class ImmutableArray<T>               // ImmutableArray`1+Builder.cs
{
    class Builder { }
}
Lucknow answered 30/6, 2015 at 3:22 Comment(1)
I know this is a year old, but I wanted to make note that this approach to naming is no longer used in the CoreFX link you've provided. They now use an underscore instead of a tick and a period instead of a plus. So the 'ImmutableArray`1+Builder.cs' would now be 'ImmutableArray_1.Builder.cs'Schuster
A
43

I think the common solution to this problem is to name the file like this:

{ClassName}`{NumberOfGenericParameters}

This would give you this filename:

Bag.cs and Bag`1.cs

This is the way Microsoft handle this issue in frameworks like Asp.net Mvc.

Amman answered 24/6, 2010 at 8:18 Comment(3)
Oh, I had not realized that the backtick is a legal character in file names (on Windows, at least). So this means that any generic type should have a backtick and a number in its name. Hmmm, I'll have to think this over. Thanks.Lucknow
@Pierre, Yes. This is how I solve the issue. However, when I have only the generic class and no non generic version I usually don't put the back-tick character in the filename. So in your case I would have the generic Map class in a file named "Map.cs".Amman
I couldn't find the example in the MVC framework, so wondered if it's still commonly done. But it's done in the entity framework, here's an example: entityframework.codeplex.com/SourceControl/latest#src/…`.csChinquapin
M
23

I have seen some libraries using

Bag.cs
Bag`1.cs
Bag`2.cs

as this is what the Type.Name would display.

I want to be more descriptive with the type parameters so I lately tend to use

Bag.cs
Bag{T}.cs
Bag{TKey, TValue}.cs

This is a format that is also supported by the XML comments.

/// <summary>
/// ...
/// Uses the <see cref="T:MyLibrary.Bag{TKey, TValue}" /> class.
/// </summary>
Membership answered 24/6, 2010 at 8:23 Comment(3)
der welten - Thank you for the suggestion. I like the idea of putting the type parameters directly into the file name better than the shorter back-tick + number naming scheme.Lucknow
I love the way they put type parameters in filename too, but in dotnet/corefx guide, they suggest use Type`{num}.cs, :(Wilhelm
github.com/dotnet/corefx/blob/master/Documentation/…Wilhelm
L
6

In the CoreFX GitHub repository, Microsoft is following the back-tick convention described in Matthias Jakobsson's answer:

enter image description here

So basically:

class ImmutableArray { }                      // ImmutableArray.cs
class ImmutableArray<T> { }                   // ImmutableArray`1.cs
...
class ImmutableDictionary<TKey, TValue> { }   // ImmutableDictionary`2.cs

And for classes defined inside other classes, the name is composed by the outer class followed by + and by the name of the inner class (Outer+Inner.cs):

partial class ImmutableArray<T>               // ImmutableArray`1+Builder.cs
{
    class Builder { }
}
Lucknow answered 30/6, 2015 at 3:22 Comment(1)
I know this is a year old, but I wanted to make note that this approach to naming is no longer used in the CoreFX link you've provided. They now use an underscore instead of a tick and a period instead of a plus. So the 'ImmutableArray`1+Builder.cs' would now be 'ImmutableArray_1.Builder.cs'Schuster
T
5

Usually if I have several types "overloaded" by the number of type parameters, it's either because one derives from the other or one is used to create the other. I just put them in the same file.

One alternative option would be to split them into different files, make one file the "primary" one, and the others "depend" on it in the build file, as per the partial class question you linked to in the question.

That way you could end up with a visual link in Visual Studio, but still one class per file to make it easier to work with them.

Termitarium answered 24/6, 2010 at 8:10 Comment(0)
B
0

I add a suffix 'T' to the names of my generic classes.

class Bag { }                           // in file Bag.cs 
class BagT<T> : Bag { }                 // in file BagT.cs
class BagInputs : BagT<Input>           // in file BagInputs.cs

You asked,

Should I put the code of both the non-generic and the generic Bag classes into the same Bag.cs file? What are your habits?

The above convention of mine is non-standard; I should clarify that I was answering "what are my habits" and not necessarily "what you should do".

Beardless answered 24/6, 2010 at 8:13 Comment(3)
That seems somewhat unusual to my mind. What would you have done if you were designing the Tuple types in .NET 4?Termitarium
@Jon - Yes, unusual: I use some non-standard naming conventions, not necessarily quite like the naming conventions of the .NET library types. I haven't met those Tuple types before, but I guess I would have called them all TupleT in the same TupleT.cs.Beardless
Interesting; thanks for the idea, but I do not like it very much. It does not fit with of all other generic types used in .NET (List<int> would become ListT<int> which feels really awkward to me).Lucknow

© 2022 - 2024 — McMap. All rights reserved.