Good practice using Enumerators - Please back it up with resources [duplicate] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have a class which uses an enumeration, the enum is currently in its own file which seems wasteful.
What is the general opinion on enums being placed within the namespace of a file that they are consumed in? Or should the enum really live in its own cs file?
Edit
I should mention that while the class in question uses these enumerations, so does external callers. In other words, another class can set these enumerations. So they are not used internally to the class, otherwise this question would be a no brainer.

I wouldn't say "wasteful" (how much does an extra file cost?), but it is often inconventient. Usually there's one class that's most closely associtated with the enum, and I put them in the same file.

This is really just a matter of preference.
I prefer to put each enumeration in its own file (likewise for each interface, class, and struct, no matter how small). It makes them easier to find when I'm coming from another solution or otherwise don't already have a reference to the type in question.
Putting a single type in each file also makes it easier to identify changes in source control systems without diffing.

This is entirely a matter of style. What I tend to do is to have a file called Enums.cs in the solution in which the enum declarations are collected.
But they are typically found through the F12 key anyway.

The question to ask yourself would be: is there anything about an enumeration type in C# that indicates I should treat it differently from all other types I create?
If the enumeration is public, it should be treated like any other public type. If it is private, declare it as a nested member of the class using it. There is no compelling reason to put two public types in the same file simply because one is an enumeration. The fact that it is a public type is all that matters; the flavor of type does not.

Another advantage of putting each type (class, struct, enum) in its own file is source control. You can easily get the entire history of the type.

I place mostly inside in namespace and outside of class so that it is easily accessible other classes in that namespace like below.
namespace UserManagement
{
public enum UserStatus { Active, InActive }
class User
{
...
}
}

Generally I prefer my enums to be in the same file as the Class that it will most probably be an attribute of. If for example I have a class Task then the enum TaskStatus will be in the same file.
However, if I have enums of a more generic nature, then I keep them contextually in various files.

It depends on what access is needed.
If the enum is only used by a single class, it's okay to declare it within that class because you don't need to use it anywhere else.
For enums used by multiple classes or in a public API, then I will always keep the definition in its own file in the appropriate namespace. It's far easier to find that way, and the strategy follows the pattern of one-object-per-file, which is good to use with classes and interfaces as well.

I think that depends on the scope of the enum. For example if the enum is specific to one class, for example used to avoid the magic constant scenario, then I would say put it in the same file as the class:
enum SearchType { Forward, Reverse }
If the enum is general and can be used by several classes for different scenarios, then I would be inclined to use put it in its own file. For example the below could be used for several purposes:
enum Result { Success, Error }

I tend to put enums in their own file for a very simple reason: as with classes and structs, it's nice to know exactly where to look if you want to find a type's definition: in the file of the same name. (To be fair, in VS you can always use "Go to Definition," too.)
Obviously, it can get out of hand. A colleague where I work even makes separate files for delegates.

One advantage of using a separate file for enums is that you can delete the original class that used the enum and write a new class using the enum.
If the enum is independent of the original class then putting it in a separate file makes future changes easier.

If you are using the USysWare File Browser add-in for Visual Studio, you can very quickly find files of particular names in your solution. Imagine looking for an enum that is not in its own file but instead buried in some file in a gigantic solution.
For small solutions, it doesn't matter, but for large ones, it becomes all the more important to keep classes and enums in their own files. You can quickly find them, edit them, and more. I highly, highly recommend putting your enum in its own file.
And as was stated... How wasteful is a file that ends up only being a couple of kb anyways?

Very simple huge advantage to separate file. When any object is in its own MyObjectName.cs file... you can go to solution explorer and type MyObjectName.cs and be shown exactly 1 file. Anything that makes debugging better is nice.
Another advantage on a similar note, if you search all files (ctrl+shft+F) for a name, you may find 20 references to the name in the same file... and that found name will be part of different objects. In the Find Results window all you can see is the line number and the file name. You would have to open the file and scroll to figure out which object the found reference was in.
Anything that makes debugging easier, I like.

If you have multiple projects in one solution. Then better create another project Utilities. Then create a Folder \Enumerations and create a nested static class. And then assign each static class where you will create enum that corresponds to the name of your projects. For example you have a project named DatabaseReader and DatabaseUsers then you may name the static class like
public static class EnumUtility {
#region --Database Readers Enum
public static class EnumDBReader {
public enum Actions { Create, Retrieve, Update, Delete};
}
#endregion
#region --Database Users Enum
public static class EnumDBUsers {
public enum UserIdentity { user, admin };
}
#endregion
}
Then entire enum that can be used in the entire solutions per projects will be declared on it. Use #region to separate each concern. By this, it is easier to look for any enums

I like to have one public enums file named E containing each seperate enum, then any enum can be accessed with E... and they are in one place to manage.

Related

StyleCop SA1402 and Generics

I think SA1402 is a great rule but I have problem with generics. I've got a class that uses the Func delegate, so the names roughly parallel that signature. That is, I have classes named Operation<TType>, Operation<T, TType>, Operation<T1, T2, TType> and so on. According to SA1402, I need to put all these small classes in separate files and come up with some strange decoration for the file name. Additionally, if I need to change one of these items I'll typically need to make changes to the rest. This seems less supportable than a single module.
Does it make sense for SA1402 to allow generics of the same basic class (as well as partials) to reside in one file? In this case all permutations of the class Operation would reside in 'Operation.cs'.
They are several nameing convension. It seems the most popular is
Operation[TType].cs
Operation[T,TType].cs
Operation[T1, T2, TType].cs
But you can also use something more classic, like
Operation`1.cs
Operation`2.cs
Operation`3.cs
(see Convention for Filenames of Generic Classes)
I tend to agree with you, in general, SA1402 is a good idea. But in this specific case, and others like it (i have a generic and non-generic implementation of the same class). Like many others I think having more than one class per file is totally fine if it makes sense. I choose to ignore this warning at a very specific Scope and Target level:
[assembly: SuppressMessage(
"StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleType",
Justification = "How else would we name generic and non generic (https://stackoverflow.com/a/4063061/516433).",
Scope = "type",
Target = "~T:Pastdev.Cli.AppResources`1<!!0>")]
Using the Operation<TType>.cs approach will work if you have overridden the StyleCop's fileNamingConvention setting (File naming conventions).
Otherwise, it works automatically if you name your file like: Operation{TType}.cs, etc. (Note the curly braces)

c# overriding enum

I know that maybe this question has been asked before, but I can't seem to find a proper solution (having in mind that I am not a C# expert but a medium level user)...
I prepared a base class including an enum (AnimationStates) for animation states that my screen objects might have (for example a Soldier might have different states whereas a bird could have another set of states..) .. The base class is serving the purpose of storing update methods and other things for my animated screen objects (like animating all of them in the same manner)... The enum in the base class is (naturally) empty inside.. I have methods written utilizing the enum members...
If I define enum in my child classes by "public new enum...", I can "inherit" it.. right ? Moreover, and interestingly, I have a Dictionary in base class and I am trying to pass it from a child (i.e. soldier, or bird) to its base (animatedobject) class ... But I can't..
I feel I am doing something wrong or missing.. Any ideas ?
Well, you cannot do it directly with enums in C#.
I would propose taking more object-oriented approach, and replace the enums with real objects. This way you define an interface IAnimationState in your base class, and add an abstract method getAnimationState() as well. In the screen object classes you just implement this method, returning some specific implementation of the interface IAnimationState. This way you can put some logic into the small animation state classes, making your project more modular.
You can't expand enums. You can create new enums in derived classes but they're distinct.
I think you should just use int constants.
An enumerated type represents a simple set of values. That's it. You are trying to use an enum as a class type when it simply doesn't fit the bill.
Just create an enum (if you actually need to) and make a "real" type for the complex operations.
enum SomeEnum { Foo, Bar }
class Whatever
{
public SomeEnum { get { return SomeEnum.Foo; } }
}
This question is a good example of developing a solution without really understanding the problem. Instead of proposing your solution and asking us to figure out the last 20% that doesn't make any sense, tell us what you are actually trying to accomplish. Someone here may have a better approach that you haven't even thought of.

C# - Creating a code file with common definitions/constants/enums etc?

In C++ I'd often create a code file containing constants, enums, #define-s, macros etc.
What's the best practice for that in C#? Do I create a static class and fill it with that data? or is there some other way ?
You don't need a static class for enums - they can be top-level (meaning: namespace level). Yes, you need a class for constants (and a static class would suffice), but I would tend to have multiple classes - one per intent. There is no need to cram them all together.
In C#, any #define only apply to that file, so there is not much point having a class for them (put them in the project / build-script instead). And macros don't exist.
If you have some items you want to define Globally, like a set of strings, I would use a static class with Static properties. I would do that if you are going to use it in more than 1 place.
If you are going to use a defined string for example in just once place, then I would put it in the class that is referencing it.
It is very important to use properties and not expose members. I have found with C++ developers I have worked with when they move to C# they expose members because they have no need for "the special logic of a property". While that may be true when you initially are writing the code. If you expose it as a member and need to do special logic then you have to refactor in a major way. While if you begin as a property then you can add the logic with no refactoring.
For Enums I tpyically define an Enum.cs file inside the folder that represents the namespace. Rather than define them inside a static class.
Macros:
Macros don't exist in C#.
#Defines:
defines are very restricted and only really used for conditional compilation. You should define them by using the project properties (or in your msbuild script) instead.
Enums:
Enums should each go in their own separate file. They don't need to be within a class, they just go directly in the name space.
Constants:
Personally I try to keep constants to a minimum, and private within a class where possible.
If you do have to make them public and globally available, use a static class (or a normal class if they relate directly to one nicely). Try to group them into classes by their use.
If you are talking about string constants, you could consider using a resource file instead if they are localizable strings.
Usually there is a class or struct for which your enum etc. particular applies. I put it in that file, under the class. It's easy to get to the definition from anywhere it's used in code. When possible, I try to put all similar entities for a namespace (or other logical grouping) in the same place.
I'd already object to that practice in C++.
Define that stuff where you need it and not in a single "dump" file. This kind of file tends to accumulate huge amounts of unused stuff over time. And it's hard to clean up because who knows, which parts of your code is using it...

What's the best way to store a group of constants that my program uses? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have various constants that my program uses... string's, int's,double's, etc... What is the best way to store them? I don't think I want an Enum, because the data is not all the same type, and I want to manually set each value. Should I just store them all in an empty class? Or is there a better way?
You probably could have them in a static class, with static read-only properties.
public static class Routes
{
public static string SignUp => "signup";
}
IMO using a class full of constants is fine for constants. If they will change semi-occasionally I recommend using AppSettings in your config and the ConfigurationManager class instead.
When I have "constants" that are actually pulled in from AppSettings or similar I still will always have a "constants" class that wraps the reading from configuration manager. It's always more meaningful to have Constants.SomeModule.Setting instead of having to resort directly to ConfigurationManager.AppSettings["SomeModule/Setting"] on any place that wants to consume said setting value.
Bonus points for this setup, since SomeModule would likely be a nested class inside the Constants file, you could easily use Dependency Injection to inject either SomeModule directly into classes that depend on it. You could also even extract an interface on top of SomeModule and then create a depenedency to ISomeModuleConfiguration in your consuming code, this would then allow you to decouple the dependency to the Constants files, and even potentially make testing easier, especially if these settings come from AppSettings and you change them using config transformations because the settings are environment specific.
What I like to do is the following (but make sure to read to the end to use the proper type of constants):
internal static class ColumnKeys
{
internal const string Date = "Date";
internal const string Value = "Value";
...
}
Read this to know why const might not be what you want. Possible type of constants are:
const fields. Do not use across assemblies (public or protected) if value might change in future because the value will be hardcoded at compile-time in those other assemblies. If you change the value, the old value will be used by the other assemblies until they are re-compiled.
static readonly fields
static property without set
This is the best way IMO. No need for properties, or readonly:
public static class Constants
{
public const string SomeConstant = "Some value";
}
An empty static class is appropriate. Consider using several classes, so that you end up with good groups of related constants, and not one giant Globals.cs file.
Additionally, for some int constants, consider the notation:
[Flags]
enum Foo
{
}
As this allows for treating the values like flags.
Another vote for using web.config or app.config. The config files are a good place for constants like connection strings, etc. I prefer not to have to look at the source to view or modify these types of things. A static class which reads these constants from a .config file might be a good compromise, as it will let your application access these resources as though they were defined in code, but still give you the flexibility of having them in an easily viewable/editable space.
I would suggest static class with static readonly. Please find the code snippet below:
public static class CachedKeysManager
{
public static readonly string DistributorList = "distributorList";
}
If these Constants are service references or switches that effect the application behavior I would set them up as Application user settings. That way if they need to be changed you do not have to recompile and you can still reference them through the static properties class.
Properties.Settings.Default.ServiceRef
Yes, a static class for storing constants would be just fine, except for constants that are related to specific types.

do interfaces belong in files of their own

As as rule of thumb I generally put classes in a file of their own. Visual studio seems to encourage this but what is appropriate with regards to interfaces?
e.g.
I have Class Foo that implements interface Bar
public interface IBar
{
}
public class Foo : IBar
{
}
it seems natural to group these within the same file until another class implements the interface but to dedicate a file to 2 lines code seems excessive but correct.
What is appropriate?
I would split them into 2 files. I often found classes starting to go unmanageable when they are not in their own files.
Imagine trying to find class Foo in a file named IBar.cs or vice versa.
Since the purpose of an interface is to define a "contract" for (potentially) multiple implementing classes, I'd say putting the interface definition in its own file makes more sense. i.e. What happens if you also want to make Baz implement Foo?
Depending on the situation I either split each interface into its own file, or alternatively have an Interfaces.cs file, where I group interfaces in a given namespace together.
I'd never put an interface in the same .cs file as a class that implemented it.
I have only two situations where I find myself putting multiple top level types in a single file:
If you're defining multiple delegate types. Each is only going to be a single declaration, so it makes sense to have a Delegates.cs file.
Sometimes it makes sense to declare that a whole bunch of autogenerated partial types implement a bunch of interfaces. Again, that's one line per type:
// Actualy code is in the autogenerated file
public partial class Foo : ICommon {}
Other than that, I use one file per top-level type, which goes for interfaces, classes and enums.
You should certainly put the interface in it's own file. You may even consider putting the interface in it's own class library. If the interface will be used by two different classes in two different libraries, it makes sense to put the interface in a third library, so you don't have to include any specific implementation if you want to add the interface to a new project. In the third library you might also place classes that work with classes that implement the interface (public void Cook(IBar x), for instance).
Yes, having an interface implies that you are going to have more than one class with the same methods and properties definitions. Having it in one file for the moment is convenient as it is easy to modify without changing files. As time goes on you will and other classes use it, and if you have to make a change to it down the road you will have to hunt and peck for the right file.
I always put them into separate files. Having more than one type per file is just distracting IMO. I might make a folder "Interfaces" for them though.
Also i think you shouldn't modify them as often as your actual implementations, anyway, so having them separated at least promotes that a bit.
In terms of encapsulation, each object, whether a class or an interface, should be in its own file. Even if the interface only contains one abstract method, the fact that it's in a different file allows for better organization and better encapsulation. You can store those different interfaces in a folder, give it an appropriate namespace, and therefore a cleaner solution.

Categories

Resources