I am trying to generate a constant value that I will be using like following:
public class Foo()
{
public const String ExtensionKey = Guid.NewGuid().ToString();
public int ID { get; set; }
}
The compiler is throwing an error:
The expression being assigned to 'Foo.ExtensionKey' must be constant
I know that it is not possible to execute a method (a constructor or a type initializer) at compile time. I am looking for a workaround to get randomly generated Guid assigned to different ExtensionKey constants of different classes.
EDIT:
The intention is to generate a UNIQUE Guid per type. The Guid value must be the same for all objects instances and whenever the application run. This is the behavior of Const and I am looking for a way to respect it.
(Much of this answer "promoted" from a comment to the question.)
In Visual Studio, you can choose "Tools" - "Create GUID". Or in Windows PowerShell you can say [Guid]::NewGuid().ToString(). That will give you a Guid. Then you can make the string representation of that particular Guid your string constant.
public const string ExtensionKey = "2f07b447-f1ba-418b-8065-5571567e63f6";
The Guid is fixed, of course. A field marked const is always static (but you must not supply the static keyword; it is implied).
If you want to have the field of Guid type, then it can't be declared const in C#. Then you would do:
public static readonly Guid ExtensionKey = new Guid("2f07b447-f1ba-418b-8065-5571567e63f6");
readonly means that the field can only be changed from a (static in this case) constructor of the same class (a constructor of a derived class is not OK).
Call to Guid.NewGuid() will return you a new GUID every time, this is why you get an exception. You can replace const with readonly or static or use a fixed GUID string with const.
public class Foo
{
// Fixed "forever" or until you manually change it
// Cannot be changed in run-time
public const String ExtensionKey = "3c88c196-06ec-4a89-bffa-6f3fd221f425";
// You will get a new GUID per each Application Domain and per each run
// Can be changed
public static String ExtensionKey1 = Guid.NewGuid().ToString();
// By convention this shall be private, as it's a field
// You will get a new GUID per each instance of a class,
// Once assigned, the value cannot be changed
public readonly String ExtensionKey3 = Guid.NewGuid().ToString();
// You will get a new GUID per each Application Domain and per each run,
// Once assigned, the value cannot be changed
public static readonly String ExtensionKey4 = Guid.NewGuid().ToString();
}
Edit
The intention is to generate a UNIQUE Guid per type. The Guid value
must be the same for all objects instances and whenever the
application run.
Generate a new GUID manually and use the first option
// Fixed "forever" or until you manually change it
// Cannot be changed in run-time
public const String ExtensionKey = "3c88c196-06ec-4a89-bffa-6f3fd221f425";
You can get almost the same behavior by replacing const with static readonly
public static readonly String ExtensionKey = Guid.NewGuid().ToString();
This question lacks a bit of details; do you want your GUID to be unique per class and process, or unique per class, but the same every time you start your program? It's two very different things.
If you want a unique GUID per class and process then you have some valid answers already, but if you want a unique GUID per class, but not per process, then you need some other way of solving your problem. Either you enter a GUID in your code, or you use some kind of GUID generator that uses some text as input instead of some random number generator based on the clock or similar.
I would suggest reading this blog post about generating a GUID from a string, the actual code resides on GitHub.
By using something like that and using the full name of the class as input you will get a unique GUID per class, but still the same for every process
Related
Is there any difference between the following?
class C
{
// One:
public static readonly int ValueAsAMember = 42;
// Two:
public static int ValueAsAProperty { get { return 42; } }
}
I'm used to writing constants the first way (unless they're private/internal, in which case I use the const keyword), but I recently saw the second form.
Is there any advantage one way over the other in terms of readability, convention, performance, or anything else?
You have three choices:
public static readonly int Value = 42;
public static int Value { get { return 42; } }
public const int Value = 42;
Choose static readonly if the value will not change at runtime but might change in future versions of your code.
Choose a property if the value might change at runtime. Of course it won't change if you use the given code.
Choose const if the value is really a constant that will not even change in future versions (something like Math.PI or int.MinValue). And of course the use of const is limited by the type of the value.
The difference between const and static readonly is that the const value will be replaced on the call site. If you change the value of a const in a future version then all assemblies that rely on your class need to be recompiled using the new value.
The property requires a method call (calling a getter is a method call). So if the value is constant at runtime there is no need for that.
Yes, there is an advantage:
If the value gets changeable at any point in the future (e.g. in a future version of your code), in a way that it is, for example, time-dependent, you can support that in the read-only property without changing the public interface of your class.
If you have to replace a readonly field with a property, you will have to recompile any other assemblies that use your class.
There are two major differences:
The first is that fields cannot be on interfaces, whereas properties can. So if you want to use this in an interface, you have to use the property.
The second, more interesting, is that readonly fields CAN be modified, while the object is being constructed. Take the following code:
public class MyTestClass
{
public readonly int MyInt = 1;
public MyTestClass()
{
MyInt = 2;
}
}
If a caller does
new MyTestClass().MyInt
they will get 2. The same goes for static constructors for a static readonly field.
The way I see it, using the first way describes the intention of the value better - which is that it is immutable. When a person is looking at the class' interface, he will see that the value is read-only, and won't have to wonder whether it can be changed later (since in the second case he can't see the property's implementation).
An important thing to note about const declarations (I don't believe it's true for readonly) is that changing the field's value constitutes an API change, even if you're just changing the value from 42 to 41. The reason is that for consts, the value is determined during compile time, which means that if I compile a module that uses your constant, and you later change it, I will still be using the old value until I recompile my module with your new version.
readonly is nice to use on things that can only be changed in your constructor. Examples of this is typical services as interfaces when you are following the TDD pattern.
In your example const is best, it's a constant after all.
readonly
const
Cheers
I think the first line making something constant or rather readonly using readonly keyword.
and the second line is making use of a property to implement readonly. Both do the same but if you compare with the IL the property would add few extra lines of code to the dll.
The main advantage for me is with readonly you are allowed to declare it anywhere in your code. But, you will get a chance to set it only once. With the setter, you declare and set in one stroke.
Yes, there's a difference between the two.
A readonly field can only be set in the constructor.
A {get; private set;} can be set at anytime from within the class.
Example:
public class Car
{
public readonly string Name;
public string color {get; private set;}
public Car()
{
Name = "Car";
Color = "Red";
}
// will fail compilation
public void ModifyName()
{
Name = "Subaru"
}
// perfectly ok
public void ModifyColor()
{
Color = "Green"
}
}
A Property is just syntactic sugar around a field, a property without a setter is simply declared a readonly field so the compiler will allow you to set it at runtime in the constructor, because to the compiler you are referencing a readonly field. There is a larger discussion around what to use a field or property, which is not within the scope of the question. And yes its this syntactic sugar that you have to do the recompiling referenced by #SOreadytohelp. Just to be clear a property is a field with a get and set method created for it, C# will allow you to reference it like a field rather than doing an annoying call to the getter or setter everytime.
I would like to know how to declare a "global" variable for a class. That is I want that this variable is available everywhere just in this class and not in the other classes.
What is the best form to declare them? or when do I use each of these forms?
I would like to have it OO.
1st Form:
enter code here
private const string _Column1= "Names";
private const string _Column2= "Numbers";
private const string _Column3= "Alarms";
2nd Form:
private enum enumColumnNames
{
Names, // integer value = 0
Numbers, // 1
Alarms, // 2
};
3rd Form:
internal sealed class clsColumnNames
{
public static readonly clsColumnNames Column1 = new clsColumnNames("Names");
public static readonly clsColumnNames Column2 = new clsColumnNames("Numbers");
public static readonly clsColumnNames Column3 = new clsColumnNames("Alarms");
private clsColumnNames(string value)
{ Value = value;
}
public string Value { get; private set; }
}
4th Form:
internal sealed class clsColumnNames
{
public static readonly string Column1 = "Names";
public static readonly string Column2= "Numbers";
public static readonly string Column3= "Alarms";
}
Thanks!
Cis
private enum enumColumnNames
{
Names, // integer value = 0
Numbers, // 1
Alarms, // 2
};
And as long as the string value is equal to the enum name you can use
enumColumnNames.Names.ToString() will produce "Names"
static class ColumnNames
{
public const string Names = "Names";
public const string Number = "Numbers";
public const string Alarms = "Alarms";
}
Since these are constants, I would recommend the enum approach. As mentioned by Amorphis, this will aloow you to get the literal value viw .ToString(). This also allows you to pass around your strings as a parameter boxed to the given values by using the enum type as a parameter, rather than a string which may or may not be one of the given values. There are some ways around this (such as converting an out-of-range int) but it's still less error-prone than passing raw strings everywhere.
Not also, however, that whenever you have front-facing text, you should use a Resource (.resx), because this allows you to adjust how the strings show up depending on the language settings of the machine running your code. If any of these strings are ever to be seen by a user, use resources!
The 1st form is the best for the following reasons:
Simplest
Less typing
The 2nd form will just result in lots of needless extra code/typing (i.e., enumColumnNames.Names.ToString(), just to get the value of your variable. I've already worn my fingers out just typing that once).
For the 3rd form, let's break it down:
Making the class internal isn't really changing anything since your variables are private
Making the class sealed just means the class cannot be inherited from; again, this is not changing anything since your variables are private
Making your variables static just means that they won't show up in an object of the class; again, not really doing anything
Making your variables readonly just means that they can only be set in a constructor
There is no point in having a property for a variable that you intend to be constant; Properties are generally used to make sure that a variable is being set/gotten properly
And for the 4th form, same gripes as with the 3rd, just minus the last gripe.
EDIT:
Since these particular variables you are asking about are supposed to be column names, I would actually recommend Amorphis' answer (sorry Amorphis, I don't have enough rep to upvote your answer just yet). If your global variables are unrelated to each other (i.e., a variable for the name of a webpage vs. a variable for the number of characters allowed in a text field are nice and dissimilar), then you ought to use the first form.
Is there any difference between the following?
class C
{
// One:
public static readonly int ValueAsAMember = 42;
// Two:
public static int ValueAsAProperty { get { return 42; } }
}
I'm used to writing constants the first way (unless they're private/internal, in which case I use the const keyword), but I recently saw the second form.
Is there any advantage one way over the other in terms of readability, convention, performance, or anything else?
You have three choices:
public static readonly int Value = 42;
public static int Value { get { return 42; } }
public const int Value = 42;
Choose static readonly if the value will not change at runtime but might change in future versions of your code.
Choose a property if the value might change at runtime. Of course it won't change if you use the given code.
Choose const if the value is really a constant that will not even change in future versions (something like Math.PI or int.MinValue). And of course the use of const is limited by the type of the value.
The difference between const and static readonly is that the const value will be replaced on the call site. If you change the value of a const in a future version then all assemblies that rely on your class need to be recompiled using the new value.
The property requires a method call (calling a getter is a method call). So if the value is constant at runtime there is no need for that.
Yes, there is an advantage:
If the value gets changeable at any point in the future (e.g. in a future version of your code), in a way that it is, for example, time-dependent, you can support that in the read-only property without changing the public interface of your class.
If you have to replace a readonly field with a property, you will have to recompile any other assemblies that use your class.
There are two major differences:
The first is that fields cannot be on interfaces, whereas properties can. So if you want to use this in an interface, you have to use the property.
The second, more interesting, is that readonly fields CAN be modified, while the object is being constructed. Take the following code:
public class MyTestClass
{
public readonly int MyInt = 1;
public MyTestClass()
{
MyInt = 2;
}
}
If a caller does
new MyTestClass().MyInt
they will get 2. The same goes for static constructors for a static readonly field.
The way I see it, using the first way describes the intention of the value better - which is that it is immutable. When a person is looking at the class' interface, he will see that the value is read-only, and won't have to wonder whether it can be changed later (since in the second case he can't see the property's implementation).
An important thing to note about const declarations (I don't believe it's true for readonly) is that changing the field's value constitutes an API change, even if you're just changing the value from 42 to 41. The reason is that for consts, the value is determined during compile time, which means that if I compile a module that uses your constant, and you later change it, I will still be using the old value until I recompile my module with your new version.
readonly is nice to use on things that can only be changed in your constructor. Examples of this is typical services as interfaces when you are following the TDD pattern.
In your example const is best, it's a constant after all.
readonly
const
Cheers
I think the first line making something constant or rather readonly using readonly keyword.
and the second line is making use of a property to implement readonly. Both do the same but if you compare with the IL the property would add few extra lines of code to the dll.
The main advantage for me is with readonly you are allowed to declare it anywhere in your code. But, you will get a chance to set it only once. With the setter, you declare and set in one stroke.
Yes, there's a difference between the two.
A readonly field can only be set in the constructor.
A {get; private set;} can be set at anytime from within the class.
Example:
public class Car
{
public readonly string Name;
public string color {get; private set;}
public Car()
{
Name = "Car";
Color = "Red";
}
// will fail compilation
public void ModifyName()
{
Name = "Subaru"
}
// perfectly ok
public void ModifyColor()
{
Color = "Green"
}
}
A Property is just syntactic sugar around a field, a property without a setter is simply declared a readonly field so the compiler will allow you to set it at runtime in the constructor, because to the compiler you are referencing a readonly field. There is a larger discussion around what to use a field or property, which is not within the scope of the question. And yes its this syntactic sugar that you have to do the recompiling referenced by #SOreadytohelp. Just to be clear a property is a field with a get and set method created for it, C# will allow you to reference it like a field rather than doing an annoying call to the getter or setter everytime.
Is it possible to declare a constant Guid in C#?
I understand that I can declare a static readonly Guid, but is there a syntax that allows me to write const Guid?
No. The const modifier only applies to "primitive" types (bool, int, float, double, long, decimal, short, byte) and strings. Basically anything you can declare as a literal.
Declare it as static readonly Guid rather than const Guid
public static readonly Guid Users = new Guid("5C60F693-BEF5-E011-A485-80EE7300C695");
and that's that.
While you can't seem to do that you can do that to be parsed whenever you need it:
const string _myGuidStr = "e6b86ea3-6479-48a2-b8d4-54bd6cbbdbc5";
But don't use the above guid as it belongs to me solely, I first generated it so I claim ownership on this particular guid above! But I'm generious - use this one instead (I don't like how it talks back to me but it's a nice guid overall when it keeps its mouth shut): 284c694d-d9cc-446b-9701-b391876c8394
I am doing it like this:
public static class RecordTypeIds
{
public const string USERS_TYPEID = "5C60F693-BEF5-E011-A485-80EE7300C695";
public static Guid Users { get { return new Guid(EntityTypeIds.USERS_TYPEID); } }
}
Depends on what you want a const for.
If you want to have a known GUID that you can reuse as needed, the above solution of storing the GUID as a string and parsing to GUID as needed works.
If you need a default parameter value, that won't work. The alternative is to use a nullable Guid and use null as your constant value.
public void Foo(string aParameter, Guid? anOptionalGuid = null)
How can I use a static Guid as argument in an attribute?
static class X
{
public static readonly Guid XyId = new Guid("---");
}
[MyAttribute(X.XyId)] // does not work
public class myClass
{
}
It does not work because Guid must be readonly, it can not be const. The string and byte[] representation would also be readonly.
Is there any workaround for this?
It's not possible and will never be possible, because [Attributes] are compiled as metadata and static variables are initialized at runtime, and of course the former cannot access the latter (except via Reflection).
If the standard
public const string MyGuid = "blah";
won't work for you, then AFAIK the only way to achieve what you want, is with Reflection.
Unfortunately there is no a good way to pass Guid to attribute.
Only workaround would be to use another type for that and convert it to Guid.