I want to see your ideas on a efficient way to check values of a newly serialized object.
Example I have an xml document I have serialized into an object, now I want to do value checks. First and most basic idea I can think of is to use nested if statments and checks each property, could be from one value checking that it has he correct url format, to checking another proprieties value that is a date but making sue it is in the correct range etc.
So my question is how would people do checks on all values in an object? Type checks are not important as this is already taken care of it is more to do with the value itself. It needs to be for quite large objects this is why I did not really want to use nested if statements.
Edit:
I want to achieve complete value validation on all properties in a given object.
I want to check the value it self not that it is null. I want to check the value for specific things if i have, an object with many properties one is of type string and named homepage.
I want to be able to check that the string in the in the correct URL format if not fail. This is just one example in the same object I could check that a date is in a given range if any are not I will return false or some form of fail.
I am using c# .net 4.
Try to use Fluent Validation, it is separation of concerns and configure validation out of your object
public class Validator<T>
{
List<Func<T,bool>> _verifiers = new List<Func<T, bool>>();
public void AddPropertyValidator(Func<T, bool> propValidator)
{
_verifiers.Add(propValidator);
}
public bool IsValid(T objectToValidate)
{
try {
return _verifiers.All(pv => pv(objectToValidate));
} catch(Exception) {
return false;
}
}
}
class ExampleObject {
public string Name {get; set;}
public int BirthYear { get;set;}
}
public static void Main(string[] args)
{
var validator = new Validator<ExampleObject>();
validator.AddPropertyValidator(o => !string.IsNullOrEmpty(o.Name));
validator.AddPropertyValidator(o => o.BirthYear > 1900 && o.BirthYear < DateTime.Now.Year );
validator.AddPropertyValidator(o => o.Name.Length > 3);
validator.Validate(new ExampleObject());
}
I suggest using Automapper with a ValueResolver. You can deserialize the XML into an object in a very elegant way using autommaper and check if the values you get are valid with a ValueResolver.
You can use a base ValueResolver that check for Nulls or invalid casts, and some CustomResolver's that check if the Values you get are correct.
It might not be exacly what you are looking for, but I think it's an elegant way to do it.
Check this out here: http://dannydouglass.com/2010/11/06/simplify-using-xml-data-with-automapper-and-linqtoxml
In functional languages, such as Haskell, your problem could be solved with the Maybe-monad:
The Maybe monad embodies the strategy of combining a chain of
computations that may each return Nothing by ending the chain early if
any step produces Nothing as output. It is useful when a computation
entails a sequence of steps that depend on one another, and in which
some steps may fail to return a value.
Replace Nothing with null, and the same thing applies for C#.
There are several ways to try and solve the problem, none of them are particularly pretty. If you want a runtime-validation that something is not null, you could use an AOP framework to inject null-checking code into your type. Otherwise you would really have to end up doing nested if checks for null, which is not only ugly, it will probably violate the Law of Demeter.
As a compromise, you could use a Maybe-monad like set of extension methods, which would allow you to query the object, and choose what to do in case one of the properties is null.
Have a look at this article by Dmitri Nesteruk: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
Hope that helps.
I assume your question is: How do I efficiently check whether my object is valid?
If so, it does not matter that your object was just deserialized from some text source. If your question regards checking the object while deserializing to quickly stop deserializing if an error is found, that is another issue and you should update your question.
Validating an object efficiently is not often discussed when it comes to C# and administrative tools. The reason is that it is very quick no matter how you do it. It is more common to discuss how to do the checks in a manner that is easy to read and easily maintained.
Since your question is about efficiency, here are some ideas:
If you have a huge number of objects to be checked and performance is of key importance, you might want to change your objects into arrays of data so that they can be checked in a consistent manner. Example:
Instead of having MyObject[] MyObjects where MyObject has a lot of properties, break out each property and put them into an array like this:
int[] MyFirstProperties
float[] MySecondProperties
This way, the loop that traverses the list and checks the values, can be as quick as possible and you will not have many cache misses in the CPU cache, since you loop forward in the memory. Just be sure to use regular arrays or lists that are not implemented as linked lists, since that is likely to generate a lot of cache misses.
If you do not want to break up your objects into arrays of properties, it seems that top speed is not of interest but almost top speed. Then, your best bet is to keep your objects in a serial array and do:
.
bool wasOk = true;
foreach (MyObject obj in MyObjects)
{
if (obj.MyFirstProperty == someBadValue)
{
wasOk = false;
break;
}
if (obj.MySecondProperty == someOtherBadValue)
{
wasOk = false;
break;
}
}
This checks whether all your objects' properties are ok. I am not sure what your case really is but I think you get the point. Speed is already great when it comes to just checking properties of an object.
If you do string compares, make sure that you use x = y where possible, instead of using more sophisticated string compares, since x = y has a few quick opt outs, like if any of them is null, return, if the memory address is the same, the strings are equal and a few more clever things if I remember correctly. For any Java guy reading this, do not do this in Java!!! It will work sometimes but not always.
If I did not answer your question, you need to improve your question.
I'm not certain I understand the depth of your question but, wouldn't you just do somthing like this,
public SomeClass
{
private const string UrlValidatorRegex = "http://...
private const DateTime MinValidSomeDate = ...
private const DateTime MaxValidSomeDate = ...
public string SomeUrl { get; set; }
public DateTime SomeDate { get; set; }
...
private ValidationResult ValidateProperties()
{
var urlValidator = new RegEx(urlValidatorRegex);
if (!urlValidator.IsMatch(this.Someurl))
{
return new ValidationResult
{
IsValid = false,
Message = "SomeUrl format invalid."
};
}
if (this.SomeDate < MinValidSomeDate
|| this.SomeDate > MinValidSomeDate)
{
return new ValidationResult
{
IsValid = false,
Message = "SomeDate outside permitted bounds."
};
}
...
// Check other fields and properties here, return false on failure.
...
return new ValidationResult
{
IsValid = true,
};
}
...
private struct ValidationResult
{
public bool IsValid;
public string Message;
}
}
The exact valdiation code would vary depending on how you would like your class to work, no? Consider a property of a familar type,
public string SomeString { get; set; }
What are the valid values for this property. Both null and string.Empty may or may not be valid depending on the Class adorned with the property. There may be maximal length that should be allowed but, these details would vary by implementation.
If any suggested answer is more complicated than code above without offering an increase in performance or functionality, can it be more efficient?
Is your question actually, how can I check the values on an object without having to write much code?
Related
I am writing a simple C#.NET application where I have an if condition where I am checking if a string variable value is a string or another string or another string or another one, etcetc.
Something like this:
if(protocollo == "2019/0002391" || protocollo == "2019/0002390" || protocollo == "2019/0001990" || ........)
This solution works but it is not so elegant. What could be a smarter way to implement the same behavior?
I agree with #JeroenMostert that it really depends on the context of the rest of your application. That said, using an array of strings and checking if your string is in there is a nice straightforward solution. There are certianily solutions that would scale better, take a look at HashSet.
string[] s = new string[] { "2019/0002391", "2019/0002390", "2019/0001990", ... };
if (s.Contains(protocollo)) {
// fill in here
}
You never said, so I'm making the assumption that the strings you're checking against is hard-coded and not something that changes often. To that end, you could create a string[] or HashSet<string> in a static class so it only initializes the one time, then expose a method for checking a second string against the valid ones.
void Main()
{
Console.WriteLine(Protocols.ValidProtocol("2019/0002391")); //True
Console.WriteLine(Protocols.ValidProtocol("2018/0000000")); //False
}
// Define other methods and classes here
public static class Protocols
{
public static bool ValidProtocol(string protocol)
{
return _validProtocols.Contains(protocol);
}
private static readonly HashSet<string> _validProtocols = new HashSet<string>
{
"2019/0002391",
"2019/0002390",
"2019/0001990"
//etc, etc...
};
}
A solution like this would probably not be ideal if the list of strings you need to check against changes often. You'd probably want to pull the list from an external source like a file or a database if you need to modify it often.
I had some code similar to your example in a static extension method. I didn't want to have to instantiate an array every time the method was called, but I wanted to improve the readability of the code.
I improved the code using the switch expression which was added in C# 8. Here is the what your example might look like if implemented with a switch expression. Depending on what your code does if the condition is true you may be able to improve on this, but this is the basics.
var isProtocolloMatch = protocollo switch
{
"2019/0002391" => true,
"2019/0002390" => true,
"2019/0001990" => true,
_ => false
};
if (isProtocolloMatch)
{
// do stuff
}
Issue:
enum's referenced by gameobject scripts via inspector variables become out of order when the enum has new entries added before the referenced index.
Details:
So I have multiple systems such as item lists, localisation strings, etc which are dynamically built by parsing external files. This parsing creates enum's which are used to reference the items by gameobject's via script inspector variables. Here's the parsed output by my localisation system as an example:
public enum LocaleID
{
LocalisedStrings_ENGB,
LocalisedStrings_ENUS,
//...
MAX,
}
public enum StringID
{
String_EMPTY,
String_Inventory,
String_Recipes,
String_Tools,
String_Journal,
//...
}
public static class LocalisedStrings
{
private static string[] SCLocalisedStrings_ENGB =
{
"",
"Inventory",
"Recipes",
"Tools",
"Journal",
//...
}
private static LocaleID currentLocale = (LocaleID)0;
private static string[] activeSC = SCLocalisedStrings_ENGB;
public static void SetLocale(LocaleID newLocale)
{
currentLocale = newLocale;
switch(newLocale)
{
case LocaleID.LocalisedStrings_ENGB:
activeSC = SCLocalisedStrings_ENGB;
break;
case LocaleID.LocalisedStrings_ENUS:
activeSC = SCLocalisedStrings_ENUS;
break;
}
}
//entry interface:
public static string Get(StringID stringID)
{
return activeSC[(int)stringID];
}
}
This simply returns the string via the enum index based off the set locale.
So I'd have something such as a name of an NPC exposed on a character as:
[SerializeField]
public StringID SpeakerTitle;
and set that through the inspector.
The issue is a rather obvious and expected one - if the enum is parsed differently, for example an extra entry is added to the top (for example for sorting purposes) or removed (for cleaning up obsolete entries), then all referenced enum's will become out of order by 1 spot since they'll be referencing the index of the enum entry.
A simple solution would be to impose a rule of only adding to the end and never removing entries that become stale. This becomes quite wasteful, so is obviously not very preferable.
What are suggested solutions to this issue? Any examples of how others approach this rather common situation? My preference would of course be something which could be sorted and new entries added anywhere, but we can't have everything we want :)
Just specify explicit numeric values for the entries:
public enum StringID
{
String_EMPTY = 0,
String_Inventory = 1,
String_Recipes = 2,
String_Tools = 3,
String_Journal = 4,
//...
}
That way the ordering is entirely irrelevant to the values. Note that you can do this retrospectively, or in a "just in time" way when you need to make what would otherwise be a breaking change.
(I'd personally get rid of the String_ prefix as well, but that's a different matter.)
I would use an explicit map rather than a naked array; for example:
private static Dictionary<StringID,string> SCLocalisedStrings_ENGB =
new Dictionary<StringID,string>
{
{StringID.String_EMPTY, ""},
{StringID.String_Inventory, "Inventory"},
//...
};
and get the value via something like:
string val;
return LocaleStrings.TryGetValue(key, out val) ? val : DefaultStrings[key];
Well... actually, I'd probably have the translations in external files as key/value pairs, but... meh.
Note: you could always put the dictionary data back into an ordered array; but having the explicit map prevents order from mattering.
I'm writing a pathfinding algorithm for a game, but trying to keep it generic so it can be used in future applications.
I have a Node class which holds X, Y and "PassableType".
The NodeGrid class stores an array of Nodes, containing the graph information of how they connect, and then has a FindAStarPath() function, which takes as its parameters StartNode, EndNode, and params for "PassableTypes".
My problem is determining what type "PassableType" should have.
Ideally what I want is to be able to use a generic enum - i.e. a restricted list which each game defines. The Node will hold a single element of that list, to say what path type it is (the current game may use Path, Grass, Wall, etc)
Thus, when an entity tries to path, it provides the pathfinding function which types to treat as "passable". So a man may use
FindAStarPath(CurrentNode, DestinationNode, "Path", "Floor", "Door");
but a car may just use
FindAStarPath(StartNode, EndNode, "Road");
My problem is I can't work out how to get the NodeGrid to take a Generic enum or equivalent logic.
At the moment I have it taking strings, but this means I have to write
MyEnum.Road.ToString()
every time I use it.
Ideally I'd like to do something like
NodeGrid<MyEnum> CurrentNodeGrid = new NodeGrid<MyEnum>()
And then Nodes will take a MyEnum for their passableType, as will the pathfinding functions, thus allowing each game to have a different set of tile types for pathing.
But I can't define NodeGrid as:
public class NodeGrid<T> where T:enum
For clarity, the only part of the pathfinding function which uses this enum is this (contained within Node):
public bool IsPassable(string[] passableTypes)
{
for (var i = 0; i < passableTypes.Count(); i++)
{
if (this.PassableType == passableTypes[i]) return true;
}
return false;
}
Thanks
Haighstrom
Unless you're using some specific functionality of enums (like Enum.Parse), then I don't see any reason to constrain it to them. By freeing constraints, callers can use whatever types they see fit, beit enum, or a set of string values (as you currently have it), or a set of custom class instances to check against.
public class NodeGrid<T>
{
public T PassableType { get; private set; }
public bool IsPassable(params T[] passableTypes)
{
return IsPassable((IEnumerable<T>)passableTypes);
}
public bool IsPassable(IEnumerable<T> passableTypes)
{
foreach(T passType in passableTypes)
{
if (EqualityComparer<T>.Default.Equals(this.PassableType, passType))
return true;
}
return false;
}
}
But since we're now using generics, you can't use the == comparison anymore. The simplest is to leverage the EqualityComparer.Default utility. The main reason to use this over directly calling this.PassableType.Equals(passType) is it will perform null checks and leverage generics properly where applicable and if the types implement IEquatable<T>, then use those generic versions. Probably some other minor things. It will usually eventually call the Object.Equals overload.
Some examples based on your question:
//using a custom enum, calls the params T[] overload
NodeGrid<MyCarEnum> carNode = ...
carNode.IsPassable(MyCarEnum.Road, MyCarEnum.Tunnel);
//demonstrates receiving a set of pass types strings from an external source
List<string> passTypes = new List<string>("Path", "Floor", "Door");
NodeGrid<string> personNode = ...
personNode.IsPassable(passTypes) //calls the IEnumerable<T> overload
//feel free to declare enums wherever you want,
//it can avoid potential mixups like this:
NodeGrid<string> airplaneNode = ...
NodeGrid<string> personNode = ...
NodeGrid<MyCarEnum> carNode = ...
airplaneNode.IsPassable("Floor"); //makes no sense, but will compile
personNode.IsPassable("Clouds"); //makes no sense, but will compile
carNode.IsPassable("Sky"); //compile error: was expected a MyCarEnum value
I'd like to restrict the value of a number parameter in a constructor to within a certain range.
I know the conventional way is to do something like the following:
public class Foo
{
public int MaxAmount { get; }
public int Amount { get; set; }
public Foo(int amount)
{
if (amount > MaxAmount) { Amount = MaxAmount; }
else if (amount < 1) { Amount = 1; }
else { Amount = amount; }
}
}
But what I don't like about this is that the caller doesn't know when the property gets set to something other than what was specified. I could return an exception instead of silently clamping the value, but that's not very friendly.
What I'd like is something akin to this:
public Foo(int(1, this.MaxAmount) amount) // Where int(minimumValue, maximumValue)
{
Amount = amount;
}
in which one wouldn't even be able to instantiate Foo with an unacceptable value - the framework would prevent it.
Is anything like this possible?
EDIT FOR CLARITY:
What I'm after is a means by which the parameter itself can carry and communicate the information about its constraints - in a 'baked in' fashion which might, for example, surface in Intellisense when you wrote the call. So, I'd avoid the work of even attempting to instantiate the class if the values for the parameters were not valid.
If, for example, the program is running and the user types a number (N) and presses a button which creates a new Foo with an illegal quantity of N, I now have an exception to handle and something to debug and fix. Why even allow it in the first place? If Foo has been explicitly defined as having an upper boundary of 4 for its Amount property, what's the point of allowing the developer to write Foo(5) when I could have informed him that the value he's passing is not valid at the time that he wrote it?
If there's some syntactic sugar, like ParameterConstraint or something, that is handled by the Framework for me so that I don't have to roll my own into every class I write, I think that would be very useful.
I could return an exception instead of silently clamping the value, but that's not very friendly.
Say what? What do you mean, "friendly"? The caller isn't your friend, it's another piece of code that is trying to set an out of range value. The developer who wrote the code should be told immediately that he's doing something wrong.
Throw an exception!
You can do this using static-contract checking with Code Contracts (Premium only - The standard edition only offers runtime contract checking).
The syntax is simply
public Foo(int amount) {
Contract.Requires(amount < MaxAmount);
...
}
(Requires) contracts are evaluated by checking that the arguments is constrained when calling the method. In your instance, it will be difficult to evaluate the constructor argument with against the instance field MaxAmount, because you cannot check that value beforehand. (Make MaxValue static to solve this).
Example of such call.
int val = _getFromSomewhere();
var foo = new Foo(val);
//This May produce compile time error
// because the contract checker cannot prove you contract is met.
The fix would be to make sure you put the constraint where you call is made.
int val = _getFromSomewhere();
if (val < Foo.MaxAmount)
var foo = new Foo(val);
//Will always compile fine, because contract is met.
When you install Contracts, the static checker isn't turned on by default. Your project properties will have an extra tab where you can configure the contract options and enable static checking.
You will need to wrap the parameter up in a new type then. ints know what their max amount is, and it is int.MaxValue. If it is truly the case that the parameter itself knows its own max amount, and that it isn't something specific to class Foo, then you will need to create another type that checks the amount passed in to it. As it stands, the signature of Foo's constructor accepts any int data structure.
Either throw the exception or provide a static property to validate the amount
public static bool ValidateAmount(int amount)
{
if(amount > MaxAmount)
return false;
return true;
}
Not for sure if this works for properties types in C#, but you might be able to define an enumeration contain all of the acceptable values and then set the data type of the property to that enumeration. That would force the caller to use the enumeration and thus know what values are acceptable. Of course, if you have a lot of values in the acceptable range, the enumeration would be unwieldy.
My app has a lot of different lookup values, these values don't ever change, e.g. US States. Rather than putting them into database tables, I'd like to use enums.
But, I do realize doing it this way involves having a few enums and a lot of casting from "int" and "string" to and from my enums.
Alternative, I see someone mentioned using a Dictionary<> as a lookup tables, but enum implementation seems to be cleaner.
So, I'd like to ask if keeping and passing around a lot of enums and casting them be a problem to performance or should I use the lookup tables approach, which performs better?
Edit: The casting is needed as ID to be stored in other database tables.
Casting from int to an enum is extremely cheap... it'll be faster than a dictionary lookup. Basically it's a no-op, just copying the bits into a location with a different notional type.
Parsing a string into an enum value will be somewhat slower.
I doubt that this is going to be a bottleneck for you however you do it though, to be honest... without knowing more about what you're doing, it's somewhat hard to recommendation beyond the normal "write the simplest, mode readable and maintainable code which will work, then check that it performs well enough."
You're not going to notice a big difference in performance between the two, but I'd still recommend using a Dictionary because it will give you a little more flexibility in the future.
For one thing, an Enum in C# can't automatically have a class associated with it like in Java, so if you want to associate additional information with a state (Full Name, Capital City, Postal abbreviation, etc.), creating a UnitedState class will make it easier to package all of that information into one collection.
Also, even though you think this value will never change, it's not perfectly immutable. You could conceivably have a new requirement to include Territories, for example. Or maybe you'll need to allow Canadian users to see the names of Canadian Provinces instead. If you treat this collection like any other collection of data (using a repository to retrieve values from it), you will later have the option to change your repository implementation to pull values from a different source (Database, Web Service, Session, etc.). Enums are much less versatile.
Edit
Regarding the performance argument: Keep in mind that you're not just casting an Enum to an int: you're also running ToString() on that enum, which adds considerable processing time. Consider the following test:
const int C = 10000;
int[] ids = new int[C];
string[] names = new string[C];
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i< C; i++)
{
var id = (i % 50) + 1;
names[i] = ((States)id).ToString();
}
sw.Stop();
Console.WriteLine("Enum: " + sw.Elapsed.TotalMilliseconds);
var namesById = Enum.GetValues(typeof(States)).Cast<States>()
.ToDictionary(s => (int) s, s => s.ToString());
sw.Restart();
for (int i = 0; i< C; i++)
{
var id = (i % 50) + 1;
names[i] = namesById[id];
}
sw.Stop();
Console.WriteLine("Dictionary: " + sw.Elapsed.TotalMilliseconds);
Results:
Enum: 26.4875
Dictionary: 0.7684
So if performance really is your primary concern, a Dictionary is definitely the way to go. However, we're talking about such fast times here that there are half a dozen other concerns I'd address before I would even care about the speed issue.
Enums in C# were not designed to provide mappings between values and strings. They were designed to provide strongly-typed constant values that you can pass around in code. The two main advantages of this are:
You have an extra compiler-checked clue to help you avoid passing arguments in the wrong order, etc.
Rather than putting "magical" number values (e.g. "42") in your code, you can say "States.Oklahoma", which renders your code more readable.
Unlike Java, C# does not automatically check cast values to ensure that they are valid (myState = (States)321), so you don't get any runtime data checks on inputs without doing them manually. If you don't have code that refers to the states explicitly ("States.Oklahoma"), then you don't get any value from #2 above. That leaves us with #1 as the only real reason to use enums. If this is a good enough reason for you, then I would suggest using enums instead of ints as your key values. Then, when you need a string or some other value related to the state, perform a Dictionary lookup.
Here's how I'd do it:
public enum StateKey{
AL = 1,AK,AS,AZ,AR,CA,CO,CT,DE,DC,FM,FL,GA,GU,
HI,ID,IL,IN,IA,KS,KY,LA,ME,MH,MD,MA,MI,MN,MS,
MO,MT,NE,NV,NH,NJ,NM,NY,NC,ND,MP,OH,OK,OR,PW,
PA,PR,RI,SC,SD,TN,TX,UT,VT,VI,VA,WA,WV,WI,WY,
}
public class State
{
public StateKey Key {get;set;}
public int IntKey {get {return (int)Key;}}
public string PostalAbbreviation {get;set;}
}
public interface IStateRepository
{
State GetByKey(StateKey key);
}
public class StateRepository : IStateRepository
{
private static Dictionary<StateKey, State> _statesByKey;
static StateRepository()
{
_statesByKey = Enum.GetValues(typeof(StateKey))
.Cast<StateKey>()
.ToDictionary(k => k, k => new State {Key = k, PostalAbbreviation = k.ToString()});
}
public State GetByKey(StateKey key)
{
return _statesByKey[key];
}
}
public class Foo
{
IStateRepository _repository;
// Dependency Injection makes this class unit-testable
public Foo(IStateRepository repository)
{
_repository = repository;
}
// If you haven't learned the wonders of DI, do this:
public Foo()
{
_repository = new StateRepository();
}
public void DoSomethingWithAState(StateKey key)
{
Console.WriteLine(_repository.GetByKey(key).PostalAbbreviation);
}
}
This way:
you get to pass around strongly-typed values that represent a state,
your lookup gets fail-fast behavior if it is given invalid input,
you can easily change where the actual state data resides in the future,
you can easily add state-related data to the State class in the future,
you can easily add new states, territories, districts, provinces, or whatever else in the future.
getting a name from an int is still about 15 times faster than when using Enum.ToString().
[grunt]
You could use TypeSafeEnum s
Here's a base class
Public MustInherit Class AbstractTypeSafeEnum
Private Shared ReadOnly syncroot As New Object
Private Shared masterValue As Integer = 0
Protected ReadOnly _name As String
Protected ReadOnly _value As Integer
Protected Sub New(ByVal name As String)
Me._name = name
SyncLock syncroot
masterValue += 1
Me._value = masterValue
End SyncLock
End Sub
Public ReadOnly Property value() As Integer
Get
Return _value
End Get
End Property
Public Overrides Function ToString() As String
Return _name
End Function
Public Shared Operator =(ByVal ats1 As AbstractTypeSafeEnum, ByVal ats2 As AbstractTypeSafeEnum) As Boolean
Return (ats1._value = ats2._value) And Type.Equals(ats1.GetType, ats2.GetType)
End Operator
Public Shared Operator <>(ByVal ats1 As AbstractTypeSafeEnum, ByVal ats2 As AbstractTypeSafeEnum) As Boolean
Return Not (ats1 = ats2)
End Operator
End Class
And here's an Enum :
Public NotInheritable Class EnumProcType
Inherits AbstractTypeSafeEnum
Public Shared ReadOnly CREATE As New EnumProcType("Création")
Public Shared ReadOnly MODIF As New EnumProcType("Modification")
Public Shared ReadOnly DELETE As New EnumProcType("Suppression")
Private Sub New(ByVal name As String)
MyBase.New(name)
End Sub
End Class
And it gets easier to add Internationalization.
Sorry about the fact that it's in VB and french though.
Cheers !
Alternatively you can use constants
If the question was "is casting enum faster than accessing a dictionary item?" then the other answers addressing the various aspects of the performance would make sense.
But here the question seems to be "is casting enum when I need to store their value to a database table going to negatively affect the application performance?".
If that is the case, I don't need to run any test to say that storing data in a database table is always going to be orders of magnitude slower than casting an enum or executing its ToString().
In this case I would say the important thing is readability and maintainability of the code. In simple cases enums will do the job cleanly, but I agree with other answers that dictionaries are more flexible in the long term.
Enums will greatly outperform almost anything, especially dictionary's. Enums only use single byte. But why would you be casting? Seems like you should be using the enums everywhere.
Avoid enum as you can: enums should be replaced by singletons deriving from a base class or implementing an interface.
The practice of using enum comes from an old style programming in C.
You start to use an enum for the US States, then you will need the number of inhabitants, the capitol..., and you will need a lot of big switches to get all of this infos.