I have something like this:
namespace MyNamespace {
public partial class MyClass: UserControl {
public static const String MYCONST = "MyConstant";
I can't see MYCONST from anywhere even from MyClass, why ?
A constant is available in a static context anyway, so remove the static keyword and you'll be fine.
MSDN docs:
The static modifier is not allowed in a constant declaration.
The reason is that a constant's value has to be fully evaluated at compile time and what the compiler does is that it takes that value and replaces all the usages of the constant throughout the code with the constant value.
That is why it sometimes can be better to use a public readonly value instead as the compiler does not replace the usages with the value but instead links to the readonly variable. This is especially something to think about when using constants from another assembly since you might not update all assemblies at once and you might end up with assmblies using the old constant value.
Ref: http://msdn.microsoft.com/en-us/library/e6w8fe1b(v=vs.80).aspx
According to the documentation for const
The static modifier is not allowed in a constant declaration.
Remove the static keyword from your constant and it should work.
Edit
Note that a const will be available as a class member, just like when you have static for non const variables. But for const the static is implicit and not allowed to type out.
What the heck kind of compiler are you using?
In general, making constants public is not a good idea. They behave differently from readonly variables, their literal value gets compiled into the IL. Which is a problem if the const is declared in another assembly. You could, say, ship a bug fix for an assembly that modified the const value. The other assemblies in your product will however continue to use the old value. The jitter won't complain about the mismatch. Not good.
A public const is only okay if it is a 'manifest' constant. Like Math.PI, only running the code in another universe could produce unexpected results. A product or company name is already pretty risky.
It should be accessible as MyNamespace.MyClass.MYCONST
You have a compile error in your code.
When I compile your code I get this:
The constant 'MyNamespace.MyClass.MYCONST' cannot be marked static
See the motivation for this error on Eric Lippert's blog:
Don't repeat yourself; consts are already static
Related
I am trying to declare a PI constant like this:
public static const double PI = Math.PI;
but why am I getting this error?
The constant 'Calendar.NewCalendar.PI' cannot be marked static
const implies static (you don't need an instance to reference the const value).
I want to also add this important point: When you link against (reference) an assembly with a public const, that value is copied into your assembly. So if the const value in the referenced assembly changes, your assembly will still have the originally compiled-in value.
If this behavior is not acceptable, then you should consider making the field a public static readonly field.
Lib.dll, provided as binary:
public class Foo {
public const int HATS = 42;
public static readonly int GLOVES = 33;
}
App.exe, references Lib.dll:
Foo.HATS // This will always be 42 even if the value in Lib.dll changes,
// unless App.exe is recompiled.
Foo.GLOVES // This will always be the same as Foo.GLOVES in Lib.dll
From MSDN:
Don’t create a constant to represent information that you expect to change at any time. For example, don’t use a constant field to store the price of a service, a product version number, or the brand name of a company. These values can change over time, and because compilers propagate constants, other code compiled with your libraries will have to be recompiled to see the changes.
From DotNetPerls:
DLLs. When you use a const field or declaration, the C# compiler actually embeds the const variable's value directly in the IL code. Therefore, it essentially erases the const as a separate entity.
Caution:
If programs that depend on a const are not recompiled after the const value changes, they may break [because they'll continue to use the previous value].
A constant is static by definition.
You can't have static const. Try readonly instead of const or simply drop the "static" since "const" is implied static anyway.
Constants cannot be replaced in the code during compilation, not runtime, so there's no requirement for static vs instance definitions.
All constants declarations are implicitly static, and the C# specification states that the (redundant) inclusion of the static modifier is prohibited. I believe this is to avoid the confusion which could occur if a reader were to see two constants, one declared static and one not – they could easily assume that the difference in specification implied a difference in semantics. Having said that, there is no prohibition on redundantly specifying an access modifier which is also the default one, where there is a choice. For instance, a (concrete) method can be explicitly marked as private despite that being the default. The rule appears to be that where there is no choice (e.g. a method declaration in an interface) the redundant modifier is prohibited. Where there is a choice, it’s allowed.
As it says. I am about to define a constant, or static, value in a program I am writing and am confused as to why you would use one or the other. As the only related question i get when asking this question deals with someone who wants to mark something as both static and constant at once I suspect I am not the only person a bit lost with these concepts.
So why would I use static and why would I use constant? What's the distinction? Are they synonymous? If so, that's cool, but if not why not? Thanks!
const is dealt with at compile time. Every reference to that constant is replaced by the constant value.
static is very different. It is a variable which exists only once but belongs to all objects of that type. It can be edited unless marked as readonly (or given a getter but no setter). If it is marked as readonly then it is essentially a constant, but it is handled at runtime, not by the compiler.
First off, they are not synonymous.
static marks a member as belonging to the type.
const means the member value cannot be changed. The value is determined at compile time and substituted wherever it appears.
For better understanding of how static is to be used, read Static Classes and Static Members.
And wouldn't you know it five minutes later I find this.
Any other comments?
I got a bit of a surprise today when I changed the value of a publicly-visible constant in a static class and then replaced an old copy of the assembly with the newly-compiled version. The surprise was that the existing program that referenced the assembly didn't pick up the new value of the constant. That is, I didn't re-compile the executable but rather just replaced that one assembly.
A full description of my experiment is at How constant is a constant?
I'll admit to being very surprised by this behavior. I understand what's going on, but I don't understand why. Is there a particular technical reason why constants couldn't be picked up at JIT time rather than compile time? Are there cases where doing that would break things?
Constants are supposed to be constant. For all time. Constants are things like the value of pi, or the number of protons in a lead atom.
If your constant changes, it wasn't really a constant; use a readonly field instead.
Also see the Framework Design Guidelines, which state:
Use constant fields for constants that will never change. The compiler burns the values of const fields directly into calling code. Therefore const values can never be changed without the risk of breaking compatibility.
Essentially, changing a constant without recompiling everything that depends on it is every bit as broken as changing the signature of a method without recompiling everything that depends on it. The compiler "bakes in" all kinds of assumptions about information about metadata from referenced assemblies when it compiles a dependent assembly. If you make any change, you cannot expect things to simply keep on working.
There is also a third way to declare "constants": a public static property.
public static string ConstString {get{return "First test";}}
This has the versioning semantics of a readonly field, but if the jitter inlines the getter it becomes a jit-time constant. And unlike const it can be used on user defined types.
I think it's a good idea to use static properties for value-types and string, but not for user defined classes, since you don't want to allocate a new instance on each property access.
I used this in my FixedPoint type like this:
public struct FixedPoint
{
private int raw;
private const fracDigits=16;
private FixedPoint(int raw)
{
this.raw=raw;
}
public static FixedPoint Zero{get{return new FixedPoint();}}
public static FixedPoint One{get{return new FixedPoint(1<<fracDigits);}}
public static FixedPoint MaxValue{get{return new FixedPoint(int.MaxValue);}}
}
I have a class below:
I want to access these default strings but C# compiler doesn't like combining Const to create a Const.
public class cGlobals
{
// Some Default Values
public class Client
{
public const string DatabaseSDF = "database.sdf";
public const string DatabaseDir = "database";
public const string DatabaseFullLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
DatabaseDir);
public const string DataSource = Path.Combine(DatabaseDir, DatabaseSDF);
}
}
Is there a better way instead of hard coding the strings? I want to make use of the Special Folders and Path.Combine.
Thanks
You must use static readonly instead of const, since const have to be a constant at compile-time.
Also, constants will actually be compiled into assemblies that are using them, so if you are referencing those fields from other assemblies you would have to recompile them if you changed the constants. This doesn't happen with static readonly fields. So either way, it's a better idea :)
I actually asked about this a while ago and I would recommend reading it and the accepted answer: static readonly vs const.
For a variable to be declared const, the assigned value has to be a compile-time constant; to use the result of a method call you need to change your variable declaration:
public static readonly string DataSource = ...;
If you think about it, this isn't a compile-time constant, in that it will give different results based on which OS you run it on. It's constant within a single execution but not a "general" constant.
Just to add to the other correct answers: a constant should logically be something that is unchanging for all time and all places. Things like the number of eggs in a dozen, the atomic number of lead, and so on. Values that change over time, like the number of countries in the European Union, or the price of a troy ounce of gold in Australian dollars, should not be modeled as constants.
In your case, the value is not logically constant for all time and all places, so don't try to use a constant.
You can use readonly instead of const.
You could also look at using app.config to store your configuration settings.
I'm afraid you will have to use
static public readonly string DatabaseFullLocation = Path.Combine(/* ... */);
instead;
Personally, I would not hard code the strings at all.
I'd put them into appSettings.
Why? Well, if you need to change those values, you'll need to recompile your code. Putting them in as appSettings will allow you to just change your config file.
You can still provide an accessor through your class.
public string DatabaseSDF
{
get
{
return System.Configuration.ConfigurationManager.AppSettings["DatabaseSDF"];
}
}
Best of both worlds, imo.
const types have to be identified at compile time, in your code you're
trying to call Path.Combine at
run-time to figure out the actual
path. And you cannot update const at
runtime.
In Application Settings you can keep these kind of Constants .
In project properties ,select the settings tab. In the grid you can set your constants.
You can get as well as set these variables even during runtime.
Message.show(My.Settings.YourVariable); //you will get the value
and set by
My.Settings.YourVariable="Vibin";
My.Settings.Save()
I think this is one of the best way.
Define a class lets say GetDirectory.
Make all methods static.
Define a class for constants.
delcate all variables with --> public static readonly string Name_Of_Var = "Any value"
From GetDirectory methods - Define the code for folder you need to access
Ex: Path.Combine(GetFolderPath(Environment.SpecialFolder. "Select name of folder"), name of constants)
Done.
Why does C# not allow const and static on the same line? In Java, you must declare a field as 'static' and 'final' to act as a constant. Why does C# not let you declare const's as final?
I make the further distinction that in Java, every interface is public and abstract, whether this is explicitly declared or not. Aren't const's effectively static in nature? WHy does C# balk at this?
const and static really do mean different things, different storage mechanism, different initialisation. static is read/write, therefore must have memory allocated for storage and must be initialised at runtime. A static can be initialised with a literal value or an expression. In contrast, a const is immutable and must be initialised with a compile time constant (typically a literal value, or an expression that can be fully evaluated at compile time). The value is known at compile time so it can be embedded directly in the generated code, therefore requires no storage to be allocated at runtime.
Constants by their nature are static, so that would be redundant.
As said before, static final in Java is the same as static readonly in C#. In fact, you are saying that this member is static and its content can't be changed. Also you can specify in both cases the value from static constructor.
But const in C# is completely different thing. It's more along the lines of constants in C (DEFINE directives) but with OOP in mind. It's static because it's constant - every instance would have this constant with the same value, no constructor can set it. Also it's possible that someone would like to access the constant without having to create an instance. When you think about it non-static constant just doesn't make sense. You can almost say that constants are not part of an object - they just use it to provide context, a strong name.
Java doesn't have an equivalent to const. You can read somewhere that static final is equivalent to DEFINE but that's just so vague. Completely different mechanism, nothing in common but in the end result in the code is the same - better maintainability and readability of the code.
You just have to stop thinking about constants in C# as static members because they are not. Think of them as OOP version of DEFINE. When you consider encapsulation only reason for final and readonly fields is to prevent your own code from accidently changing its value. And that doesn't sound like constant to me.
Sumary:
final = readonly
static final = static readonly
N/A = const
It is true that a C# const implies static BUT, C# has an equivalent to Java's final keyword in the keyword readonly.
So, in fact, C# allows a const final, it is static readonly in C#.
Because allowing and not requiring modifiers that are inherent can cause confusion. If you see
static const int A = 3
const int B = 5
you may believe that they are 2 different kinds of constants.
Even VB 2008 (which can be very verbose if you wish) doesn't allow that.