Assume we want to define a class that contains all constants that we will use in our solution. And this class doesn't have any methods.
public class _const
{
/// Group1: 'DataBase'. We naming "db" group
public const Server_Name = 'ServerName';
public const DB_Name = 'DBName';
public const DB_User = 'UserName';
public const DB_Password = 'Password';
/// Group2: 'Default Variable'. We naming "default" group
public const Title= 'DefaultTitle';
public const KeyWord = 'DefaultKeyWord';
/// Group3: 'Status' constans.We naming "status" group
public const Approved = 'Approved';
public const Rejected = 'Rejected';
public const Suspended = 'Suspended';
/// And so on...
/// ...
/// ...
/// ...
}
We know, these constants will be used anywhere in the solution simply with below instruction. And don't need to create an instance of the class.
/// For example:
string x = _const.Approved;
My question is: for easier use and more code readability, is there any way for grouping related constant together? And access to each group with own prefix name (like namespace)?
Something similar to the following code.
/// For example:
string x = _const.db.DB_Name;
string y = _const.default.KeyWord;
string z = _const.status.Approved;
I think a mix of Enum and Dictionary could help you since, though with a little more verbose call, it assures consistency throughout your code:
public enum Db
{
Server_Name,
DB_Name,
DB_User,
DB_Password,
}
public enum Default
{
Title,
Keyword
}
public enum Status
{
Approved,
Rejected,
Suspened
}
public static class _const
{
public static Dictionary<Db, string> db = new Dictionary<Db, string>()
{
{Db.Server_Name, "ServerName"},
{Db.DB_Name, "DBName"},
{Db.DB_User, "UserName"},
{Db.DB_Password, "Password"}
};
public static Dictionary<Default, string> defaults = new Dictionary<Default, string>()
{
{Default.Title, "DefaultTitle"},
{Default.Keyword, "DefaultKeyWord"}
};
public static Dictionary<Status, string> status = new Dictionary<Status, string>()
{
{Status.Approved, "Approved"},
{Status.Rejected, "Rejected"},
{Status.Suspened, "Suspended"}
};
}
that you can use in your code like:
string string_x = _const.db[Db.Server_Name];
string string_y = _const.defaults[Default.Keyword];
string string_z = _const.status[Status.Suspened];
You can make your class static and define another nested static class like this:
public static class Constants
{
public static class Group1
{
internal const string String1 = "String1";
}
}
internal class Program
{
internal static void Main()
{
Console.WriteLine(Constants.Group1.String1);
}
}
Related
I created a new class called DashObject, then immediately created an example DashObject. But when I try to access it, the IDE says it doesn't exist.
I'm trying to manage Amazon Dash devices using this class, but I can't even access them once defined for some reason.
class DashObject
{
// Definitions
string DashName;
string DashIdentifier;
int DashFunction;
string DashFunctionInfo;
// Constructor
public DashObject(string dashName, string dashIdentifier, int dashFunction, string dashFunctionInfo)
{
DashName = dashName;
DashIdentifier = dashIdentifier;
DashFunction = dashFunction;
DashFunctionInfo = dashFunctionInfo;
}
}
//Create example DashObject
DashObject example = new DashObject("Example", "44650DFD85E9", 1, "prsl");
//Attempt to access example (this line causes build to fail)
MessageBox.Show(example.DashName);
Make sure you have a public or internal access modifier on it. Change your code to:
public class DashObject
{
// Definitions
public string DashName;
public string DashIdentifier;
public int DashFunction;
public string DashFunctionInfo;
// Constructor
public DashObject(string dashName, string dashIdentifier, int dashFunction, string dashFunctionInfo)
{
DashName = dashName;
DashIdentifier = dashIdentifier;
DashFunction = dashFunction;
DashFunctionInfo = dashFunctionInfo;
}
}
in order to access the field you must set it to public or internal:
public string DashName;
or
internal string DashName;
Scenario: there is a list of string constants (over 100 now, will be more in future) which are defined like this:
public const string ChildA = "Child A";
public const string ChildASomeParameter = "Some parameter";
public const string ChildASomeOtherParameter = "Some other parameter";
...
public const string ChildB = "Child B";
public const string ChildBSomeParameter = "Some different parameter";
public const string ChildBSomeOtherParameter = "Some parameter"; // values are not unique
...
Problem: it's not pretty to use this with intellisense : when ChildA is needed you may get intellisense offering ChildASomeParameter99999 instead. Scrolling that or typing name fully is obviously not efficient.
I had idea to move parameters into nested types, like this
public const string ChildA = "Child A";
public class ChildA
{
public const string SomeParameter1 = "Some parameter 1";
public const string SomeParameter2 = "Some parameter 2";
}
But then there is a compile time issue:
The type 'MyConstants' already contains a definition for 'ChildA'
I need help (ideas) of how to deal with that issue.
My thoughts:
put ChildA into another nested type? This will add overhead: ChildA will be used more frequently than any of its parameters, using static really shine here, having to type something like Childs.ChildA is not fast.
rename something? Rename ChildA to something ugly _ChildA? Or rename nested type to something ugly? What name wouldn't be ugly then?
Maybe someone knows a better way?
How about using Current for current class?
static void Main(string[] args)
{
System.Console.WriteLine(Constants.ChildA.Current);
System.Console.WriteLine(Constants.ChildB.SomeOtherParameter);
System.Console.WriteLine(Constants.ChildA.SomeParameter);
}
public static class Constants
{
public static class ChildA
{
public const string Current = "Child A";
public const string SomeParameter = "Some parameter";
public const string SomeOtherParameter = "Some other parameter";
}
public static class ChildB
{
public const string Current = "Child B";
public const string SomeParameter = "Some different parameter";
public const string SomeOtherParameter = "Some parameter";
}
}
Use Namespaces.
Using Namespaces (C# Programming Guide)
Like this:
namespace N1 // N1
{
class C1 // N1.C1
{
class C2 // N1.C1.C2
{
}
}
namespace N2 // N1.N2
{
class C2 // N1.N2.C2
{
}
}
}
Option 1:
public class ChildA
{
public const string Name = "Child A"
public const string SomeParameter1 = "Some parameter 1";
public const string SomeParameter2 = "Some parameter 2";
}
Option 2 (with constrains):
public class ChildA
{
public const string SomeParameter1 = nameof(SomeParameter1);
public const string SomeParameter2 = nameof(SomeParameter2);
}
usage: nameof(ChildA), nameof(ChildA.SomeParameter1)
To elaborate on constraints:
cannot use arbitrary strings
nameof returns only top-level name. E.g. nameof(ChildA.ChildAA.Param1) == "Param1"
I'm developing a class which contains some const strings
public static class Constants
{
public const string CarID= "car_id";
//public const string NumberID= "number_id"; // this is the second const string might be added, so
//the new created function can return the two
}
public class CarENParameters
{
public string Params { get; set; }
public CarENParameters(string carId)
{
Params = carId;
}
}
public static class CarPropertyProcess
{
//test params
public static CarENProps Parse(Uri uri,string content)
{
string carID= Regex.Matches(content, #"\$\('#CarXL'\)\.val\((\d+)\)", RegexOptions.None)[0].Groups[1].Value;
var parameters = new Dictionary<string, string>
{
{Constants.CarID, carID},
};
return new CarENProps(uri.AbsoluteUri, parameters);
}
public static CarENParameters GetParameters()
{
return new CarENParameters(Constants.CarID);
}
}
In the class Constants, I have one carID, now the case is it might have more than one const string like : public const string NumberID= "number_id";
So I want to create one function to return a list of those const strings, which are car_id and number_id with a class name CarENParameters but I havent figured out how to return a list by a get/set in a class, should I use dictionary or keyvaluespair to achieve that ? I'm quite new to C# so hope that I can have a better point of view from the helps of you guys. Thanks
Are you looking for something like this:
public static List<CarENParameters> GetParameters()
{
return new List<CarENParameters>()
{
new CarENParameters(Constants.CarID1),
new CarENParameters(Constants.CarID2),
new CarENParameters(Constants.CarID3)
}
}
You can use reflection for this
don't forget to put using System.Reflection;
// get class type
Type type = typeof(Constants);
// get a list of fields
FieldInfo[] fields = type.GetFields();
List<CarENParameters> list = new List<CarENParameters>();
// loop on field list
foreach (FieldInfo field in fields)
{
// if field is a string add it to our return list
if (field.FieldType == typeof(String))
list.Add(new CarENParameters((String) field.GetValue(null)));
}
First of all sorry for the confusing title, I could not find the exact words to describe the situation. But it's easy to understand with an example.
We have a static class that holds the table names as a catalog like this:
public static class Tables
{
public const string Employees= "DBEmploy1";
public const string Sales = "Sale1";
// (...etc)
}
And use them in our code like this:
string sql = "select name, surname from " + Tables.Employees + " where code='1'"
But sometimes we need to prefix the database connection or another prefix/suffix to the tables. The current solution is to declare a second Table catalog:
public static class CurrentDB1Prefix = "[databasex].dbo."
public static class Tables
{
public const string Employees = "DBEmploy1";
public const string Sales = "Sale1";
// (...etc)
}
public static class TablesP
{
public static readonly string Employees = CurrentDB1Prefix + Employees;
public static readonly string Sales = CurrentDB1Prefix + Sales;
// (...etc)
}
And use them in our code like:
string sql = "select name, surname from " + TablesP.Employees + " where code='1'"
To save effort maintaining two table lists we would like to do something like this:
public static class CurrentDB1Prefix = "[databasex].dbo."
public static class Tables
{
public const string Employees= "DBEmploy1";
public const string Sales = "Sale1";
// (...etc)
}
public static class TablesP
{
//this would return the above Table class variables with the prefixes somehow
return CurrentDB1Prefix + Table.TableVariablex;
}
How can this be done? Or some approximation as usable as this?
Don't use static and don't use const. Make the values runtime-changable by converting the fields to properties. Like this:
public class Tables
{
public string CurrentPrefix = ...;
public string Employees { get { return CurrentPrefix + "DBEmploy1" };
//(...etc)
}
I have a list of enums as follows:
public enum EventID : uint
{
SAMPLE_EVENT_1 = 0xDCCA0000,
SAMPLE_EVENT_2 = 0xDCCB0001,
SAMPLE_EVENT_3 = 0xDCCA0002,
SAMPLE_EVENT_4 = 0xDCC00003,
SAMPLE_EVENT_5 = 0xDCCA0004,
...
}
The hex value for each enum is deciphered as follows:
/// DCC X XXXX
/// --- - ----
/// | | |--> Notification ID (0x0000 to 0xFFFF)
/// | |-----> Notification Type (0x0 to 0xA)
/// |--------> Sub-system ID (0xDCC)
What is the best way to assign values to the enum's, such that adding enum's later won't mean reassigning all the values. The only Sub-system ID, and Notification Type are chosen, the Notification ID should be automatically assigned.
For example, it might get annoying if there were thousands of enum's and I had to number them by hand or renumber them if adding an enum in the middle.
Thanks.
If you asked me, you shouldn't be encoding this data in your enum values. It would be better to apply attributes the them instead where you could get this information. Let the actual value of the enum represent the NotificationId to get the automatically assigned values.
[AttributeUsage(AttributeTargets.Field, AllowMultiple=false)]
public class SubsystemIdAttribute : Attribute
{
public SubsystemIdAttribute(ushort value)
{
this.Value = (ushort)(value & 0xFFF);
}
public ushort Value { get; private set; }
}
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class NotificationTypeAttribute : Attribute
{
public NotificationTypeAttribute(byte value)
{
this.Value = (byte)(value & 0xF);
}
public byte Value { get; private set; }
}
public enum EventId
{
[SubsystemId(0xDCC)] [NotificationType(0xA)] SAMPLE_EVENT_1,
[SubsystemId(0xDCC)] [NotificationType(0xB)] SAMPLE_EVENT_2,
[SubsystemId(0xDCC)] [NotificationType(0xA)] SAMPLE_EVENT_3,
[SubsystemId(0xDCC)] [NotificationType(0x0)] SAMPLE_EVENT_4,
[SubsystemId(0xDCC)] [NotificationType(0xA)] SAMPLE_EVENT_5,
}
public static class EventIdExtensions
{
public static ushort GetSubsystemId(this EventId eventId)
{
return GetAttributeValue(eventId, (SubsystemIdAttribute a) => a.Value);
}
public static byte GetNotificationType(this EventId eventId)
{
return GetAttributeValue(eventId, (NotificationTypeAttribute a) => a.Value);
}
private static TValue GetAttributeValue<TAttribute, TValue>(EventId eventId, Func<TAttribute, TValue> selector)
where TAttribute : Attribute
{
return typeof(EventId).GetField(eventId.ToString())
.GetCustomAttributes(false)
.OfType<TAttribute>()
.Select(selector)
.Single();
}
}
To get the values of the attributes, call the appropriate extension methods.
var eventId = EventId.SAMPLE_EVENT_3;
var subsystemId = eventId.GetSubsystemId(); // 0xDCC
var notificationType = eventId.GetNotificationType(); // 0xA
Enums only auto-increment by 1, so you'd have to keep them in order by sub-system, then notification type, then notification id, and only when there are gaps would you assign. So to keep order proper, your above enum would look like this:
public enum EventID : uint
{
SAMPLE_EVENT_1 = 0xDCCA0000,
SAMPLE_EVENT_3 = 0xDCCA0002,
SAMPLE_EVENT_5 = 0xDCCA0004,
SAMPLE_EVENT_2 = 0xDCCB0001,
SAMPLE_EVENT_4 = 0xDCC00003,
}
I guess that purpose of your enums is to give a names to the events with specific codes. The question is what is the canonical source of association between names and codes. If it is you (or your code) I don't see any reason to renumber. If it comes from some external source (e.g. documentation) try to deploy some code generation (e.g. T4 templates).
If you are happy with Jeff's answer this is imho much more cleaner design
public class EventId
{
public static readonly SAMPLE_EVENT_1 = new EventId(0xDCC, 0xA);
public static readonly SAMPLE_EVENT_2 = new EventId(0xDCC, 0xA);
public static readonly SAMPLE_EVENT_3 = new EventId(0xDCC, 0xA);
public static readonly SAMPLE_EVENT_4 = new EventId(0xDCC, 0xA);
public readonly ushort SubSystemId;
public readonly byte NotificationType;
public readonly ushort NotificationId;
private static ushort notificationCounter = 0;
private EventId(ushort subSystemId, byte notificationType)
{
this.SubSystemId = subSystemId;
this.NotificationType= notificationType;
this.NotificationId = notificationCounter++;
}
}
But of course you creating dependency between compiler and NotificationId which you probably don't like.