I've always been in the habit of defining constants at the class level:
public class MyClass
{
private const int SomeNumber = 10;
...
}
But, I recently worked with someone who believes that if a constant is only used by a specific method it should be defined in that method:
public class MyClass
{
public void SomeMethod()
{
const int SomeNumber = 10;
...
}
}
My only argument for preferring the first is that if the constant is needed in other methods there is no refactoring needed and also it makes it easier to update constants since they'll be defined in the same place.
Are there any other pros/cons or is there no real difference?
If it needs updating it's not really a constant. I mean, you don't often refactor the value of Pi. Things that change belong in a configuration file in my opinion.
That said, I usually use class level public constants.
I've never seen or used method-level constants. Conceptually, a method level constant makes little sense to me.
A common reasoning against globals, singletons, etc. is that the scope of everything should be limited as far as (reasonably) possible. I agree - the smaller the scope, the less code can break when someone messes with it and the less code can mess with it. This reasoning doesn't quite apply to constants. But still, if it is only needed in a single method, define it there. If only to prevent some fool from using it in a completely unrelated context because it happens to fit, breaking stuff when the "constant" does change (which shouldn't be often - otherwise it's not a constant but should go in a configuration file - but still).
As for "less refactoring if other methods need to access the constant"... YAGNI.
The method level const hints to the compiler that the variable will not change so it can optimize for that case. Which is great if you are in the habit of hard-coding strings or numbers into your methods that are not used outside those methods. Which is not, imho, a good habit.
i would go with your approach of defining at least at class level. so that same constant can be seen by various methods of class.
or even better approach
define all constant in a single class so that all those constants can be seen by differnt classes through out your solution eevn if you want to change some logic in the constant calculation you can do it at a centrilized place.
Related
As far as I know, private is the default everywhere in C# (meaning that if I don't write public, protected, internal, etc. it will be private by default). (Please correct me if I am wrong.)
So, what's the reason to write that keyword, or why does it even exist for members?
For example, when an event handler is auto-generated it looks like this:
private void RatTrap_MouseEnter(object sender, CheeseEventArgs e)
{
}
But why does it even write private if that's implied and default? Just so that novice developers (who don't know it's the C# default) know that it's private? Or is there a difference for the compiler?
Moreover, is there a case where writing "private" (alone) will change the accessibility of the member?
AFAIK, private is the default everywhere in C# (meaning that if I don't write public, protected, internal, etc. it will be private by default). (please correct me if wrong).
This is not true. Types defined within a namespace (classes, structs, interfaces, etc) will be internal by default. Also, members within different types have different default accessibilities (such as public for interface members). For details, see Accessibility Levels on MSDN.
Also,
So, what's the reason to write that keyword, or why does it even exist?
Specifying this explicitly helps denote your intention to make the type private, very explicitly. This helps with maintainability of your code over time. This can help with other developers (or yourself) knowing whether a member is private by default or on purpose, etc.
AFAIK, private is the default everywhere in C#
Not quite - the default is "the most restricted access available for this declaration". So for example, with a top-level type the default is internal; for a nested type the default is private.
So, what's the reason to write that keyword, or why does it even exist?
It makes it explicit, which is good for two reasons:
It makes it clearer for those who don't know the defaults, as per your question (I've never liked this argument, personally, but I figured it's worth mentioning)
It gives an impression that you've deliberately decided to make it private, rather than just gone with the defaults.
As for your last part:
Moreover is there a case where writing "private" (alone) will change the accessibility of the member?
Yes, for making half of a property more restrictive than the other:
// Public getter, public setter
public int Foo { get; set; }
// Public getter, private setter
public int Bar { get; private set; }
I used to go with defaults everywhere I could, but I've been convinced (partly by Eric Lippert) that making it clear that you've thought about it and decided to make something private is a good idea.
Personally I wish there were a way of doing that for sealed / unsealed, too, for type declarations - possibly not even have a default. I suspect that many developers (myself included if I'm not careful) leave classes unsealed just because it's less effort than making them sealed.
private adds visual clutter. To those who insist that it makes things explicit, I would ask: Do you do this with mathematics, too? For instance:
var answer = a + b / c;
Do you find that unclear without redundant parentheses around b / c?
The rule in C# is very simple: By default, everything is as close to private as it can be. So if you need something to be more visible than the default, add a modifier. Otherwise, don't add needless keywords to your code.
As far as I know, private is the default everywhere in C#
Explicitly declaring private, means you know it is private. Not just think it is, because as far as you know, it is the default. It also means that someone else who looks at the code knows what it is.
There is no "I think it is", "I'm pretty sure it is", etc. It just is. And everyone is on the same page.
I am not a C# developer. If I had to work with some code that wasn't explicitly declared private, I would probably assume it was internal.
I dislike when things are implicitly set. It's never as clear as when they are explicitly set.
Readability - Not everyone may know that private is the default behaviour.
Intent - Gives a clear indication that you have specifically declared the property private (for whatever reason).
Readability, demonstration of intent are two great reasons I can think of.
One good reason for explicitly specifying the visibility is so that you don't have to think about what is the default for the context you are in.
Another good reason is because FxCop tells you to do it.
A lot of people (people like me!) regularly program in a handful of different languages. Being explicit with things like these prevents me from needing to remember all the arcane details of all the languages I program in.
I'd say for consistency with the readability of the scope of the rest of the class.
I like to explicitly add the private keyword so that I know it's private. Plus, private isn't always the default access specifier everywhere. Also, you can use private set in properties to effectively make a read-only property that can only be set by the class it was declared in.
I started working on a large c# code base and found the use of a static class with several const ints fields. This class is acting exactly like an enum would.
I would like to convert the class to an actual enum, but the powers that be said no. The main reason I would like to convert it is so that I could have the enum as the data type instead of int. This would help a lot with readability.
Is there any reason to not use enums and to use const ints instead?
This is currently how the code is:
public int FieldA { get; set; }
public int FieldB { get; set; }
public static class Ids
{
public const int ItemA = 1;
public const int ItemB = 2;
public const int ItemC = 3;
public const int ItemD = 4;
public const int ItemE = 5;
public const int ItemF = 6;
}
However, I think it should be the following instead:
public Ids FieldA { get; set; }
public Ids FieldB { get; set; }
I think many of the answers here ignore the implications of the semantics of enums.
You should consider using an enum when the entire set of all valid values (Ids) is known in advance, and is small enough to be declared in program code.
You should consider using an int when the set of known values is a subset of all the possible values - and the code only needs to be aware of this subset.
With regards to refactoring - when time and business contraints allow, it's a good idea to clean code up when the new design/implementation has clear benefit over the previous implementation and where the risk is well understood. In situations where the benefit is low or the risk is high (or both) it may be better to take the position of "do no harm" rather than "continuously improve". Only you are in a position to judge which case applies to your situation.
By the way, a case where neither enums or constant ints are necessarily a good idea is when the IDs represent the identifiers of records in an external store (like a database). It's often risky to hardcode such IDs in the program logic, as these values may actually be different in different environments (eg. Test, Dev, Production, etc). In such cases, loading the values at runtime may be a more appropriate solution.
Your suggested solution looks elegant, but won't work as it stands, as you can't use instances of a static type. It's a bit trickier than that to emulate an enum.
There are a few possible reasons for choosing enum or const-int for the implementation, though I can't think of many strong ones for the actual example you've posted - on the face of it, it seems an ideal candidate for an enum.
A few ideas that spring to mind are:
Enums
They provide type-safety. You can't pass any old number where an enum value is required.
Values can be autogenerated
You can use reflection to easily convert between the 'values' and 'names'
You can easily enumerate the values in an enum in a loop, and then if you add new enum members the loop will automatically take them into account.
You can insert new enunm values without worrying about clashes occurring if you accidentally repeat a value.
const-ints
If you don't understand how to use enums (e.g. not knowing how to change the underlying data type of an enum, or how to set explicit values for enum values, or how to assign the same value to mulitple constants) you might mistakenly believe you're achieving something you can't use an enum for, by using a const.
If you're used to other languages you may just naturally approach the problem with consts, not realising that a better solution exists.
You can derive from classes to extend them, but annoyingly you can't derive a new enum from an existing one (which would be a really useful feature). Potentially you could therefore use a class (but not the one i your example!) to achieve an "extendable enum".
You can pass ints around easily. Using an enum may require you to be constantly casting (e.g.) data you receive from a database to and from the enumerated type. What you lose in type-safety you gain in convenience. At least until you pass the wrong number somewhere... :-)
If you use readonly rather than const, the values are stored in actual memory locations that are read when needed. This allows you to publish constants to another assembly that are read and used at runtime, rather than built into the other assembly, which means that you don't have to recompile the dependant assembly when you change any of the constants in your own assembly. This is an important consideration if you want to be able to patch a large application by just releasing updates for one or two assemblies.
I guess it is a way of making it clearer that the enum values must stay unchanged. With an enum another programmer will just drop in a new value without thinking, but a list of consts makes you stop and think "why is it like this? How do I add a new value safely?". But I'd achieve this by putting explicit values on the enums and adding a clear comment, rather than resorting to consts.
Why should you leave the implementation alone?
The code may well have been written by an idiot who has no good reason for what he did. But changing his code and showing him he's an idiot isn't a smart or helpful move.
There may be a good reason it's like that, and you will break something if you change it (e.g. it may need to be a class due to being accessed through reflection, being exposed through external interfaces, or to stop people easily serializing the values because they'll be broken by the obfuscation system you're using). No end of unnecessary bugs are introduced into systems by people who don't fully understand how something works, especially if they don't know how to test their changes to ensure they haven't broken anything.
The class may be autogenerated by an external tool, so it is the tool you need to fix, not the source code.
There may be a plan to do something more with that class in future (?!)
Even if it's safe to change, you will have to re-test everything that is affected by the change. If the code works as it stands, is the gain worth the pain? When working on legacy systems we will often see existing code of poor quality or just done a way we don't personally like, and we have to accept that it is not cost effective to "fix" it, no matter how much it niggles. Of course, you may also find yourself biting back an "I told you so!" when the const-based implementation fails due to lacking type-safety. But aside from type-safety, the implementation is ultimately no less efficient or effective than an enum.
If it ain't broke, don't fix it.
I don't know the design of the system you're working on, but I suspect that the fields are integers that just happen to have a number of predefined values. That's to say they could, in some future state, contain more than those predefined values. While an enum allows for that scenario (via casting), it implies that only the values the enumeration contains are valid.
Overall, the change is a semantic one but it is unnecessary. Unnecessary changes like this are often a source of bugs, additional test overhead and other headaches with only mild benefits. I say add a comment expressing that this could be an enum and leave it as it is.
Yes, it does help with readability, and no I cannot think of any reason against it.
Using const int is a very common "old school" of programming practice for C++.
The reason I see is that if you want to be loosely coupled with another system that uses the same constants, you avoid being tightly coupled and share the same enum type.
Like in RPC calls or something...
Consider:
class Foo
{
static Foo()
{
// Static initialisation
}
}
Why are the () required in static Foo() {...}? The static constructor must always be parameterless, so why bother? Are they necessary to avoid some parser ambiguity, or is it just to maintain consistency with regular parameterless constructors?
Since it looks so much like an initialiser block, I often find myself leaving them out by accident and then have to think for a few seconds about what is wrong. It would be nice if they could be elided in the same way.
Because it's a static constructor, so it's static + a normal-looking constructor.
Consistency is key. :-)
I get this sort of question frequently; that is, the question "the compiler could work out that this thing is missing, so why is it required?" Here's another example of this sort of question:
C# using consts in static classes
As I noted in that question, basically we have three choices in that situation. Make the redundant text required, make it optional, or make it illegal.
Each has its own downside.
The downside of making it required is you end up with an unnecessary redundancy in the language.
The downside of making it optional is you confuse people who think there must be a difference between the two forms. Also, you make it harder for the error-recovering parser to do its work; it thrives on redundancy. And you potentially make it harder to add new language features in the future, because more "syntactic area" is already claimed.
The downside of making it illegal is you then make a "gotcha", where the user has to remember that oh, yeah, I'm supposed to put parens here, but not here.
The proposed feature had better have an upside that pays for the downside. The smallest downside seems to me to be the first: make it required. The other options I would want to have an upside that justifies the downside, and I'm not seeing one here.
I would assume it's for disambiguity: it makes the parser's job easier, recognising the code block as a constructor subroutine (irrespective of staticness); and conversely it helps ensure that the human author/maintainer is aware of the implications of choosing this particular construct, by forcing them to use a specific method-like syntax.
Obviously there can't be an instance member on a static class, since that class could never be instantiated. Why do we need to declare members as static?
I get asked questions like this all the time. Basically the question boils down to "when a fact about a declared member can be deduced by the compiler should the explicit declaration of that fact be (1) required, (2) optional, or (3) forbidden?"
There's no one easy answer. Each one has to be taken on a case-by-case basis. Putting "static" on a member of a static class is required. Putting "new" on a hiding, non-overriding method of a derived class is optional. Putting "static" on a const is forbidden.
Briefly considering your scenario, it seems bizarre to make it forbidden. You have a whole class full of methods marked "static". You decide to make the class static and that means you have to remove all the static modifiers? That's weird.
It seems bizarre to make it optional; suppose you have a static class and two methods, one marked static, one not. Since static is not normally the default, it seems natural to think that there is intended to be a difference between them. Making it optional seems to be potentially confusing.
That leaves making it required, as the least bad of the three options.
See http://blogs.msdn.com/b/ericlippert/archive/2010/06/10/don-t-repeat-yourself-consts-are-already-static.aspx for more thoughts on these sorts of problems.
Because by definition, all of their members must be static. They decided not to give some confusing syntactic sugar.
I would go one step further and ask: Why does C# have static classes at all? It seems like a weird concept, a class that's not really a class. It's just a container, you can't use it to type any variables, parameters or fields. You also can't use it as a type parameter. And of course, you can never have an instance of such a class.
I'd rather have modules, like in VB.NET and F#. And then, the static modifier would not be necessary to avoid confusion.
It could be implicit, but also it would complicate code reading and lead to confusions.
Richard,
Hmmmm... I'd guess that the language designers decided that it would be better to be very, very explicit... to avert any possible confusion when a maintainer, who doesn't know the code, jumps into the middle of a static class, and presumes that they are in a "normal" instance context.
But of course, that's just a guess. Most IDE's help you out there anyway, by adding the static modifier "automagically"... or at least highlighting your mistake at "write time", as apposed to "compile time".
It's a good question... unfortunately not one with a "correct" answer... unless someone can turn up a link from a C#-language-designers blog (or similar) discussing this decision. What I can tell you is: "I'd bet $1,000 that it's no accident."
Cheers. Keith.
Explicit coding makes things maintainable
If I want to copy a method from one class to another, so that code is better organized, then I would have to keep cheking a lot of things all the time, just in case the destination class is or is not static.
By declaring the member as static, you also have a visual indication of what the code is, when you see it.
It is also less confusing. Imagine a class that is static, and inside it has got members marked as static, and others not marked.
I can see lots of reasons, and many other reasons exist.
One reason I would think it is important to explicitly state it is a static is because in a multi-threaded programming model, these static variables are shared by multiple threads. When doing code review or code analysis, it is much easier to pick up this importance from reading the variable, instead of looking up the class declaration, and determine if the variables are static or non-static. It can get pretty confusing when reading variable during code review if you don't know if the class is static or non-static.
This is because copy-paste would be more complicated.
If you copy a method from a static class to a non-static class then you would have to add the static keyword.
If you copy a method from a non-static class to a static class you would have to remove the static keyword.
Moving methods around is the primary thing developers do ('I need to refactor this code, it will take a week at least'), and by making it easier Eric and his team allowed us to save hours of work.
This seems basic but Im finding this quite trivial. Simply how would you recommend setting a global variable with a static class (i.e. console-application)?
To give you a little more background the main method is calling some custom eventhandlers that I hope to get / set the variables.
Any ideas or suggestions you have is appreciated.
Simplest way is
public static Object MyGlobalVariable;
which creates a public static field. A little better is:
public static Object MyGlobalVariable { get; set; }
Which creates a public static property.
There are no global variables in C#. A variable is always locally-scoped. The fundamental unit of code is the class, and within a class you have fields, methods, and properties.
You can mimic a "global variable" by making a public static field or property in some class, but you shouldn't. C# makes this difficult for a very good reason; global variables are pure evil. They violate several good principles of OO design - encapsulation, loose coupling, and high cohesion, to name just a few.
I realize this is a beginner question, but I think it's because this is a beginner question that it's so important to be saying this. Now is the best time to start learning what tactics are actively discouraged or even dangerous in C#, and using a static field/property as a global variable is about six of them. There are legitimate uses for these constructs, but passing data around from place to place is not one of them.
If two different classes depend upon the same information, then pass the information from the source to the destination. This is usually done either through the constructor or as an argument to the method being called. You should always have one and only one instance that truly "owns" this information; making information "global" means that you can't reason about who or what might be depending on it at any given point in time.
Please consider this, and try to think about other ways you could share the information that you want to store in a global variable (i.e. by providing it as an argument to a constructor or method). If you're not sure, post an example of what you're trying to do and we'll help out.
Not 100% sure but you could try a singleton to hold your variables. Without knowing what you are trying to accomplish it's hard to recommend if this solution wouldn't bite you down the road.
http://www.yoda.arachsys.com/csharp/singleton.html