Const string referencing another const string - how to avoid DRY without readonly - c#

public static class Abc
{
public const string Placeholder = "{$content}";
public const string Pattern = $"<div class=\"embed-responsive\">{Placeholder}</div>";
}
How to correctly solve this to avoid breaching DRY (Dont repeat yourself)? I know I can use static readonly, but then it is a bit of a different thing (even though it works..). I think there should be better way? Or is there really not?

While you cannot call a method to initialize a constant value, it is allowed to use operators. If you need to create a constant that contains another constant value, use the plus operator to concatenate string values.
public static class Abc
{
public const string Placeholder = "{$content}";
public const string Pattern = "<div class=\"embed-responsive\">" + Placeholder + "</div>";
}

Related

Compute string constant at compile time with ternary operator

Q: Is there a way to make the sample below compile in C# or something similar in spirit?
public class Switch
{
public const bool Value = true;
}
public class A
{
private const string Id = "foo" + (Switch.Value ? "Dev" : String.Empty);
}
The main problem here is String.Empty, which is not a const expression, even though it will always evaluate to "".
So if you try this:
public class Switch
{
public const bool Value = true;
}
public class A
{
private const string Id = "foo" + (Switch.Value ? "Dev" : "");
}
it should compile right away, at least it does in C# 7.3.
Note that const really mean constant.
For instance, if you put the above two classes in two different projects, rebuild both, then go and change Switch.Value to false, and only rebuild that project, then A.Value will stay put, it will not "re-evaluate", because that was done at the time that was built.
It is generally not a good idea to use const for anything that isn't really constant, except if you're always rebuilding the whole solution, everything, the whole application, at the same time, then it might be OK.
However I would still use a readonly field/property for this, instead of a const.

Where to define constants and use them anywhere?

In Java I would write something like
public interface ICar {
static String RED_CAR = "/res/vehicles/car_red.png";
static String BLUE_CAR = "/res/vehicles/car_blue.png";
static String GREEN_CAR = "/res/vehicles/car_green.png";
}
Because C# doesn't allow using fields in interface, where do I define this constants in C#, when I wish to use them more than once?
You can define a static class to contain your constants (which need to be public as by default fields without modifier are private):
public static class Car
{
public const string RED_CAR = "/res/vehicles/car_red.png";
public const string BLUE_CAR = "/res/vehicles/car_blue.png";
public const string GREEN_CAR = "/res/vehicles/car_green.png";
}
After this you can use constants like Car.RED_CAR.
If all your constants are files it's better to include them in your resources.
In your project properties there's a resource section, vs can create a Resources.resx if you need one.
In there you can add all sorts of files or strings (for translations mostly).
You can then access them through Properties.Resources.RED_CAR
I would not name them like that though. It's from the time when all variables where globals and naming conventions like that where needed to know what was stored in the variable. But when accessing your data like this it's always clear what's going on.

Proper way for string literals

I have some -really long- string literals in my application. Does it differ to define them in a method like:
public string DoSomething()
{
string LongString = "...";
// ...
}
or as a const field in the lass like:
private const string LongString = "...";
public string DoSomething()
{
// ...
}
The DoSomething() method will be called many many times, is the LongString created and destroyed each time if I define it inside the method, or the compiler takes care?
String literals get interned by the CLR. Effectively meaning they will be created only once.
There is no difference between the two, the string will not be created and destroyed many times in the method. .NET uses string interning, so distinct string literals are only defined once.
In your first example, it would only be available in the function. In your second it would be available to other functions in that same class.

constant string Alternative working with helper classes

When working with switch case, for example
I could use
const string FirstFloor = "lvl1", SecondFloor = "lvl2", ThirdFloor = "lvl3";
string ElavaetTo= "lvl1";
switch(ElavaetTo)
{
case FirstFloor:
Response.Redirect(FirstFloor + "Page.aspx")
break;
case SecondFloor:
Response.Redirect(SecondFloor + "Page.aspx")
break;
case ThirdFloor:
Response.Redirect(ThirdFloor + "Page.aspx")
break;
}
Edited :
this is only an example of where constant string wil not work if placed in another class
this is not a function / method i am trying to correct so it will work.
thanks for your time, i am trying to base my methods , my approach...
This would work fine placed in the current or same class of the project but when all variables are stored outside this class instead of simply instantiating the class and methods only once :
fullClassName shrtNm = New fullClassName();
then you would like to call it as with
shrtNm.MethodName();
You need to go the 'Long way around' specially if not including the Namespace via using statement
and you would have to call it like:
string strnm = MyNameOfNameSpace.fullClassName.ConstantntStrName;
instead of:
string strnm = shrtNm.ConstantStrName;
Is there an alternative to using any type that will represent string values inside the IntelliSense in an easy way ?
I have tried to use
public enum Elavation
{
lvl1,
lvl2,
lvl3
}
but then you need to declare it as in the long example plus a .ToString()
Is there any alternative at all?
Instead of declaring the variables as 'const' have your tired declaring them as 'readonly' ?
This would enable you to simply instantiat the class only once :
fullClassName shrtNm = New FullClassName();
then you would like to call it as with
shrtNm.<VariableName>;
Guessing from the use case you enumerated, I doubt the difference between using const and readonly should matter...
as far as i could get (only because it was important for me to addapt an aproach )
i found an example in a codeProjec page about using strings and String-Enumerations
that lead me to use that aproach and then turn my calss into a static class
public static class Qs
{
public sealed class Act
{
//private Act();
public const string edit = "edit", add = "add", remove = "remove", replace = "replace";
}
public sealed class State
{
public const string addnewTableRow = "addnewTableRow", cancelInsert = "cancelInsert", loadpagefromlink="loadpagefromlink";
}
public sealed class Params
{
public const string state = "state";
public const string custID = "custID";
public const string recordID = "recordID";
}
}
using sealed class accessing it via its parent className.Itsname
e.g.
Qs.Act.edit
as edit would show in IntelliSense

Centralizing Regular Expression Validation Patterns in ASP.Net MVC

I there a way in ASP.Net MVC to have a RegularExpression attribute on a model property to pull the pattern string property from resource file or another class?
When I attempt to use another class I get a message stating that the attribute values must be a constant, typeof expression, or an array.
Ultimately, I'm attempting to abstract some of these patterns so I don't have to update multiple files if a bug is located in a pattern.
Example:
public class MyModel{
[RegularExpression(StaticPatternClass.EmailPattern, ErrorMessage="invalid email")]
public string email { get; set;}
}
public static class StaticPatternClass{
public static string EmailPattern = #"My pattern here";
}
Try
public const string EmailPattern ....
instead
The error description is quite clear, it needs to be a constant. A constant value is compiled and cannot be changed. However a regular static string might be changed (more exactly replaced as strings are immutable) during the execution of the program which is not allowed. Try this instead:
public static class StaticPatternClass{
public const string EmailPattern = #"My pattern here";
}

Categories