Validate Enum Values - c#

I need to validate an integer to know if is a valid enum value.
What is the best way to do this in C#?

You got to love these folk who assume that data not only always comes from a UI, but a UI within your control!
IsDefined is fine for most scenarios, you could start with:
public static bool TryParseEnum<TEnum>(this int enumValue, out TEnum retVal)
{
retVal = default(TEnum);
bool success = Enum.IsDefined(typeof(TEnum), enumValue);
if (success)
{
retVal = (TEnum)Enum.ToObject(typeof(TEnum), enumValue);
}
return success;
}
(Obviously just drop the ‘this’ if you don’t think it’s a suitable int extension)

IMHO the post marked as the answer is incorrect.
Parameter and data validation is one of the things that was drilled into me decades ago.
WHY
Validation is required because essentially any integer value can be assigned to an enum without throwing an error.
I spent many days researching C# enum validation because it is a necessary function in many cases.
WHERE
The main purpose in enum validation for me is in validating data read from a file: you never know if the file has been corrupted, or was modified externally, or was hacked on purpose.
And with enum validation of application data pasted from the clipboard: you never know if the user has edited the clipboard contents.
That said, I spent days researching and testing many methods including profiling the performance of every method I could find or design.
Making calls into anything in System.Enum is so slow that it was a noticeable performance penalty on functions that contained hundreds or thousands of objects that had one or more enums in their properties that had to be validated for bounds.
Bottom line, stay away from everything in the System.Enum class when validating enum values, it is dreadfully slow.
RESULT
The method that I currently use for enum validation will probably draw rolling eyes from many programmers here, but it is imho the least evil for my specific application design.
I define one or two constants that are the upper and (optionally) lower bounds of the enum, and use them in a pair of if() statements for validation.
One downside is that you must be sure to update the constants if you change the enum.
This method also only works if the enum is an "auto" style where each enum element is an incremental integer value such as 0,1,2,3,4,.... It won't work properly with Flags or enums that have values that are not incremental.
Also note that this method is almost as fast as regular if "<" ">" on regular int32s (which scored 38,000 ticks on my tests).
For example:
public const MyEnum MYENUM_MINIMUM = MyEnum.One;
public const MyEnum MYENUM_MAXIMUM = MyEnum.Four;
public enum MyEnum
{
One,
Two,
Three,
Four
};
public static MyEnum Validate(MyEnum value)
{
if (value < MYENUM_MINIMUM) { return MYENUM_MINIMUM; }
if (value > MYENUM_MAXIMUM) { return MYENUM_MAXIMUM; }
return value;
}
PERFORMANCE
For those who are interested, I profiled the following variations on an enum validation, and here are the results.
The profiling was performed on release compile in a loop of one million times on each method with a random integer input value. Each test was ran more than 10 times and averaged. The tick results include the total time to execute which will include the random number generation etc. but those will be constant across the tests. 1 tick = 10ns.
Note that the code here isn't the complete test code, it is only the basic enum validation method. There were also a lot of additional variations on these that were tested, and all of them with results similar to those shown here that benched 1,800,000 ticks.
Listed slowest to fastest with rounded results, hopefully no typos.
Bounds determined in Method = 13,600,000 ticks
public static T Clamp<T>(T value)
{
int minimum = Enum.GetValues(typeof(T)).GetLowerBound(0);
int maximum = Enum.GetValues(typeof(T)).GetUpperBound(0);
if (Convert.ToInt32(value) < minimum) { return (T)Enum.ToObject(typeof(T), minimum); }
if (Convert.ToInt32(value) > maximum) { return (T)Enum.ToObject(typeof(T), maximum); }
return value;
}
Enum.IsDefined = 1,800,000 ticks
Note: this code version doesn't clamp to Min/Max but returns Default if out of bounds.
public static T ValidateItem<T>(T eEnumItem)
{
if (Enum.IsDefined(typeof(T), eEnumItem) == true)
return eEnumItem;
else
return default(T);
}
System.Enum Convert Int32 with casts = 1,800,000 ticks
public static Enum Clamp(this Enum value, Enum minimum, Enum maximum)
{
if (Convert.ToInt32(value) < Convert.ToInt32(minimum)) { return minimum; }
if (Convert.ToInt32(value) > Convert.ToInt32(maximum)) { return maximum; }
return value;
}
if() Min/Max Constants = 43,000 ticks = the winner by 42x and 316x faster.
public static MyEnum Clamp(MyEnum value)
{
if (value < MYENUM_MINIMUM) { return MYENUM_MINIMUM; }
if (value > MYENUM_MAXIMUM) { return MYENUM_MAXIMUM; }
return value;
}
-eol-

As others have mentioned, Enum.IsDefined is slow, something you have to be aware of if it's in a loop.
When doing multiple comparisons, a speedier method is to first put the values into a HashSet. Then simply use Contains to check whether the value is valid, like so:
int userInput = 4;
// below, Enum.GetValues converts enum to array. We then convert the array to hashset.
HashSet<int> validVals = new HashSet<int>((int[])Enum.GetValues(typeof(MyEnum)));
// the following could be in a loop, or do multiple comparisons, etc.
if (validVals.Contains(userInput))
{
// is valid
}

Update 2022-09-27
As of .NET 5, a fast, generic overload is available: Enum.IsDefined<TEnum>(TEnum value).
The generic overload alleviates the performance issues of the non-generic one.
Original Answer
Here is a fast generic solution, using a statically-constucted HashSet<T>.
You can define this once in your toolbox, and then use it for all your enum validation.
public static class EnumHelpers
{
/// <summary>
/// Returns whether the given enum value is a defined value for its type.
/// Throws if the type parameter is not an enum type.
/// </summary>
public static bool IsDefined<T>(T enumValue)
{
if (typeof(T).BaseType != typeof(System.Enum)) throw new ArgumentException($"{nameof(T)} must be an enum type.");
return EnumValueCache<T>.DefinedValues.Contains(enumValue);
}
/// <summary>
/// Statically caches each defined value for each enum type for which this class is accessed.
/// Uses the fact that static things exist separately for each distinct type parameter.
/// </summary>
internal static class EnumValueCache<T>
{
public static HashSet<T> DefinedValues { get; }
static EnumValueCache()
{
if (typeof(T).BaseType != typeof(System.Enum)) throw new Exception($"{nameof(T)} must be an enum type.");
DefinedValues = new HashSet<T>((T[])System.Enum.GetValues(typeof(T)));
}
}
}
Note that this approach is easily extended to enum parsing as well, by using a dictionary with string keys (minding case-insensitivity and numeric string representations).

Brad Abrams specifically warns against Enum.IsDefined in his post The Danger of Oversimplification.
The best way to get rid of this requirement (that is, the need to validate enums) is to remove ways where users can get it wrong, e.g., an input box of some sort. Use enums with drop downs, for example, to enforce only valid enums.

This answer is in response to deegee's answer which raises the performance issues of System.Enum so should not be taken as my preferred generic answer, more addressing enum validation in tight performance scenarios.
If you have a mission critical performance issue where slow but functional code is being run in a tight loop then I personally would look at moving that code out of the loop if possible instead of solving by reducing functionality. Constraining the code to only support contiguous enums could be a nightmare to find a bug if, for example, somebody in the future decides to deprecate some enum values. Simplistically you could just call Enum.GetValues once, right at the start to avoid triggering all the reflection, etc thousands of times. That should give you an immediate performance increase. If you need more performance and you know that a lot of your enums are contiguous (but you still want to support 'gappy' enums) you could go a stage further and do something like:
public abstract class EnumValidator<TEnum> where TEnum : struct, IConvertible
{
protected static bool IsContiguous
{
get
{
int[] enumVals = Enum.GetValues(typeof(TEnum)).Cast<int>().ToArray();
int lowest = enumVals.OrderBy(i => i).First();
int highest = enumVals.OrderByDescending(i => i).First();
return !Enumerable.Range(lowest, highest).Except(enumVals).Any();
}
}
public static EnumValidator<TEnum> Create()
{
if (!typeof(TEnum).IsEnum)
{
throw new ArgumentException("Please use an enum!");
}
return IsContiguous ? (EnumValidator<TEnum>)new ContiguousEnumValidator<TEnum>() : new JumbledEnumValidator<TEnum>();
}
public abstract bool IsValid(int value);
}
public class JumbledEnumValidator<TEnum> : EnumValidator<TEnum> where TEnum : struct, IConvertible
{
private readonly int[] _values;
public JumbledEnumValidator()
{
_values = Enum.GetValues(typeof (TEnum)).Cast<int>().ToArray();
}
public override bool IsValid(int value)
{
return _values.Contains(value);
}
}
public class ContiguousEnumValidator<TEnum> : EnumValidator<TEnum> where TEnum : struct, IConvertible
{
private readonly int _highest;
private readonly int _lowest;
public ContiguousEnumValidator()
{
List<int> enumVals = Enum.GetValues(typeof (TEnum)).Cast<int>().ToList();
_lowest = enumVals.OrderBy(i => i).First();
_highest = enumVals.OrderByDescending(i => i).First();
}
public override bool IsValid(int value)
{
return value >= _lowest && value <= _highest;
}
}
Where your loop becomes something like:
//Pre import-loop
EnumValidator< MyEnum > enumValidator = EnumValidator< MyEnum >.Create();
while(import) //Tight RT loop.
{
bool isValid = enumValidator.IsValid(theValue);
}
I'm sure the EnumValidator classes could written more efficiently (it’s just a quick hack to demonstrate) but quite frankly who cares what happens outside the import loop? The only bit that needs to be super-fast is within the loop. This was the reason for taking the abstract class route, to avoid an unnecessary if-enumContiguous-then-else in the loop (the factory Create essentially does this upfront).
You will note a bit of hypocrisy, for brevity this code constrains functionality to int-enums. I should be making use of IConvertible rather than using int's directly but this answer is already wordy enough!

Building upon Timo's answer, here is an even faster, safer and simpler solution, provided as an extension method.
public static class EnumExtensions
{
/// <summary>Whether the given value is defined on its enum type.</summary>
public static bool IsDefined<T>(this T enumValue) where T : Enum
{
return EnumValueCache<T>.DefinedValues.Contains(enumValue);
}
private static class EnumValueCache<T> where T : Enum
{
public static readonly HashSet<T> DefinedValues = new HashSet<T>((T[])Enum.GetValues(typeof(T)));
}
}
Usage:
if (myEnumValue.IsDefined()) { ... }
Update - it's even now cleaner in .NET 5:
public static class EnumExtensions
{
/// <summary>Whether the given value is defined on its enum type.</summary>
public static bool IsDefined<T>(this T enumValue) where T : struct, Enum
{
return EnumValueCache<T>.DefinedValues.Contains(enumValue);
}
private static class EnumValueCache<T> where T : struct, Enum
{
public static readonly HashSet<T> DefinedValues = new(Enum.GetValues<T>());
}
}

This is how I do it based on multiple posts online. The reason for doing this is to make sure enums marked with Flags attribute can also be successfully validated.
public static TEnum ParseEnum<TEnum>(string valueString, string parameterName = null)
{
var parsed = (TEnum)Enum.Parse(typeof(TEnum), valueString, true);
decimal d;
if (!decimal.TryParse(parsed.ToString(), out d))
{
return parsed;
}
if (!string.IsNullOrEmpty(parameterName))
{
throw new ArgumentException(string.Format("Bad parameter value. Name: {0}, value: {1}", parameterName, valueString), parameterName);
}
else
{
throw new ArgumentException("Bad value. Value: " + valueString);
}
}

You can use the FluentValidation for your project. Here is a simple example for the "Enum Validation"
Let's create a EnumValidator class with using FluentValidation;
public class EnumValidator<TEnum> : AbstractValidator<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable
{
public EnumValidator(string message)
{
RuleFor(a => a).Must(a => typeof(TEnum).IsEnum).IsInEnum().WithMessage(message);
}
}
Now we created the our enumvalidator class; let's create the a class to call enumvalidor class;
public class Customer
{
public string Name { get; set; }
public Address address{ get; set; }
public AddressType type {get; set;}
}
public class Address
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Town { get; set; }
public string County { get; set; }
public string Postcode { get; set; }
}
public enum AddressType
{
HOME,
WORK
}
Its time to call our enum validor for the address type in customer class.
public class CustomerValidator : AbstractValidator<Customer>
{
public CustomerValidator()
{
RuleFor(x => x.type).SetValidator(new EnumValidator<AddressType>("errormessage");
}
}

To expound on the performance scaling specifically regarding Timo/Matt Jenkins method:
Consider the following code:
//System.Diagnostics - Stopwatch
//System - ConsoleColor
//System.Linq - Enumerable
Stopwatch myTimer = Stopwatch.StartNew();
int myCyclesMin = 0;
int myCyclesCount = 10000000;
long myExt_IsDefinedTicks;
long myEnum_IsDefinedTicks;
foreach (int lCycles in Enumerable.Range(myCyclesMin, myCyclesMax))
{
Console.WriteLine(string.Format("Cycles: {0}", lCycles));
myTimer.Restart();
foreach (int _ in Enumerable.Range(0, lCycles)) { ConsoleColor.Green.IsDefined(); }
myExt_IsDefinedTicks = myTimer.ElapsedTicks;
myTimer.Restart();
foreach (int _ in Enumerable.Range(0, lCycles)) { Enum.IsDefined(typeof(ConsoleColor), ConsoleColor.Green); }
myEnum_IsDefinedTicks = myTimer.E
Console.WriteLine(string.Format("object.IsDefined() Extension Elapsed: {0}", myExt_IsDefinedTicks.ToString()));
Console.WriteLine(string.Format("Enum.IsDefined(Type, object): {0}", myEnum_IsDefinedTicks.ToString()));
if (myExt_IsDefinedTicks == myEnum_IsDefinedTicks) { Console.WriteLine("Same"); }
else if (myExt_IsDefinedTicks < myEnum_IsDefinedTicks) { Console.WriteLine("Extension"); }
else if (myExt_IsDefinedTicks > myEnum_IsDefinedTicks) { Console.WriteLine("Enum"); }
}
Output starts out like the following:
Cycles: 0
object.IsDefined() Extension Elapsed: 399
Enum.IsDefined(Type, object): 31
Enum
Cycles: 1
object.IsDefined() Extension Elapsed: 213654
Enum.IsDefined(Type, object): 1077
Enum
Cycles: 2
object.IsDefined() Extension Elapsed: 108
Enum.IsDefined(Type, object): 112
Extension
Cycles: 3
object.IsDefined() Extension Elapsed: 9
Enum.IsDefined(Type, object): 30
Extension
Cycles: 4
object.IsDefined() Extension Elapsed: 9
Enum.IsDefined(Type, object): 35
Extension
This seems to indicate there is a steep setup cost for the static hashset object (in my environment, approximately 15-20ms.
Reversing which method is called first doesn't change that the first call to the extension method (to set up the static hashset) is quite lengthy. Enum.IsDefined(typeof(T), object) is also longer than normal for the first cycle, but, interestingly, much less so.
Based on this, it appears Enum.IsDefined(typeof(T), object) is actually faster until lCycles = 50000 or so.
I'm unsure why Enum.IsDefined(typeof(T), object) gets faster at both 2 and 3 lookups before it starts rising. Clearly there's some process going on internally as object.IsDefined() also takes markedly longer for the first 2 lookups before settling in to be bleeding fast.
Another way to phrase this is that if you need to lots of lookups with any other remotely long activity (perhaps a file operation like an open) that will add a few milliseconds, the initial setup for object.IsDefined() will be swallowed up (especially if async) and become mostly unnoticeable. At that point, Enum.IsDefined(typeof(T), object) takes roughly 5x longer to execute.
Basically, if you don't have literally thousands of calls to make for the same Enum, I'm not sure how hashing the contents is going to save you time over your program execution. Enum.IsDefined(typeof(T), object) may have conceptual performance problems, but ultimately, it's fast enough until you need it thousands of times for the same enum.
As an interesting side note, implementing the ValueCache as a hybrid dictionary yields a startup time that reaches parity with Enum.IsDefined(typeof(T), object) within ~1500 iterations. Of course, using a HashSet passes both at ~50k.
So, my advice: If your entire program is validating the same enum (validating different enums causes the same level of startup delay, once for each different enum) less than 1500 times, use Enum.IsDefined(typeof(T), object). If you're between 1500 and 50k, use a HybridDictionary for your hashset, the initial cache populate is roughly 10x faster. Anything over 50k iterations, HashSet is a pretty clear winner.
Also keep in mind that we are talking in Ticks. In .Net a 10,000 ticks is 1 ms.
For full disclosure I also tested List as a cache, and it's about 1/3 the populate time as hashset, however, for any enum over 9 or so elements, it's way slower than any other method. If all your enums are less than 9 elements, (or smaller yet) it may be the fastest approach.
The cache defined as a HybridDictionary (yes, the keys and values are the same. Yes, it's quite a bit harder to read than the simpler answers referenced above):
//System.Collections.Specialized - HybridDictionary
private static class EnumHybridDictionaryValueCache<T> where T : Enum
{
static T[] enumValues = (T[])Enum.GetValues(typeof(T));
static HybridDictionary PopulateDefinedValues()
{
HybridDictionary myDictionary = new HybridDictionary(enumValues.Length);
foreach (T lEnumValue in enumValues)
{
//Has to be unique, values are actually based on the int value. Enums with multiple aliases for one value will fail without checking.
//Check implicitly by using assignment.
myDictionary[lEnumValue] = lEnumValue;
}
return myDictionary;
}
public static readonly HybridDictionary DefinedValues = PopulateDefinedValues();
}

I found this link that answers it quite well. It uses:
(ENUMTYPE)Enum.ToObject(typeof(ENUMTYPE), INT)

To validate if a value is a valid value in an enumeration, you only need to call the static method Enum.IsDefined.
int value = 99;//Your int value
if (Enum.IsDefined(typeof(your_enum_type), value))
{
//Todo when value is valid
}else{
//Todo when value is not valid
}

Related

Delegate vs if statement

I have a class:
public class MyClass: IMyInterface
{
int _parameter;
public Myclass(int parameter)
{
_parameter = parameter;
//Do other things
}
public int FrequentlyCalledFunction()
{
if(_parameter == 0)
{
return 0;
}
else
{
int result;
//Do some calculations
return result;
}
}
}
Since the _parameter is assigned once in the constructor, entering the if statement every time the FrequentlyCalledFunction is called seems somewhat inefficient for an already created instance .
Thus, I thought to modify the code as follows. Declare a delegate
public delegate int MyDlg();
public class MyClass: IMyInterface
{
int _parameter;
MyDlg _intermediate;
public Myclass(int parameter)
{
_parameter = parameter;
_intermediate = _parameter == 0 ? _returnZero : _calculateAndReturn;
//Do other things
}
public int FrequentlyCalledFunction()
{
return _intermediate();
}
int _returnZero()
{
return 0;
}
int _calculateAndReturn()
{
int result;
//Do some calculations
return result;
}
}
So now, the check will be performed only once at the moment of creating the instance. On the other hand the if statement is replaced with an additional delegate call.
The question is, assuming that the performance is very important, which approach is better?
P.S.
The FrequentlyCalledFunction is a method from the interface IMyInterface, thus, I cannot define a MyDlg FrequentlyCalledFunction and call it from the outside of the class.
You are thinking about it too much. The best way to improve performance in this case is to make MyClass abstract, and to define two subclasses: MyClassWithCalculations and MyClassWithoutCalculations.
When you are about to create an instance of MyClass, check the parameter: if it is zero, instantiate MyClassWithoutCalculations. If it is non-zero, instantiate MyClassWithCalculations. No delegates, no ifs, no convoluted stuff.
That having been said, let me also add that you are probably wrong in thinking that an innocent if( variable == 0 ) statement can affect performance in any significant way whatsoever.
I came across this question trying whilst searching for ideas to improve the performance in an existing app. The scenario:
Stream of updates that arrive at a rate of 44 Hz (every ~23ms)
Updates are only 16 bytes of data
What happens to the update (how it should be transformed before being output to a consuming system) depends on the value of a Guid.
That Guid...
Changes relatively infrequently -- not for 8 hours, then a couple of times over 10 minutes.
Changes as a result of a call from a separate system.
The objective was to reduce the time between receiving an update and posting a value out to a consuming system.
In my scenario, an if statement checking the Guid on every update vs a delegate being used to point to another function had cost of 4ms. For us, it was worth swapping out as all our other optimisations were sub 1ms.
I guess the real answer is "test, test, test", but I thought I'd share my experience.

ConcurrentDictionary adding same keys more than once

I want to use ConcurrentDictionary to check if this data key has been added before, but it looks like I can still add keys which added before.
code:
public class pKeys
{
public pKeys()
{ }
public pKeys(long sID, long pID)
{
this.seID = sID;
this.pgID = pID;
}
public long seID;
public long pgID;
}
public static ConcurrentDictionary<pKeys, bool> existenceDic
= new ConcurrentDictionary<pKeys, bool>();
test code:
pKeys temKey = new pKeys(111, 222);
bool res = existenceDic.TryAdd(temKey, true);
Console.WriteLine(res);
temKey = new pKeys(111, 222);
res = existenceDic.TryAdd(temKey, true);
Console.WriteLine(res);
result:
true
true
You can add two different instances containing the same values, because you haven't overridden GetHashCode() and Equals(). This causes the default equality comparison to be used, which for reference types simply compares the references themselves. Two different instances are always considered as different values in this case.
One option is to make your type a struct instead of class. This uses a default comparison that will take into account the field values.
Alternatively, you can go ahead and override GetHashCode() and Equals(). For example:
public class pKeys
{
public pKeys()
{ }
public pKeys(long sID, long pID)
{
this.seID = sID;
this.pgID = pID;
}
public readonly long seID;
public readonly long pgID;
public override int GetHashCode()
{
return seID.GetHashCode() * 37 + pgID.GetHashCode();
}
public override bool Equals(object other)
{
pKeys otherKeys = other as pKeys;
return otherKeys != null &&
this.seID == otherKeys.seID &&
this.pgID == otherKeys.pgID;
}
}
Notes:
The hash code is calculated based on the hash codes of the individual values. One is multiplied by 37, which is simply a convenient prime number; some people prefer to use a much larger prime number for better "mixing". For most scenarios, the above will work fine IMHO.
Note that your proposed solution, converting the values to strings, concatenating them, and returning the hash code of that has several negative aspects:
You have to create three string instances just to generate the hash code! The memory overhead alone is bad enough, but of course there is the cost of formatting the two integers as well.
Generating a hash code from a string is more expensive computationally than from an integer value
You have a much higher risk of a collision, as it's easier for disparate values to result in the same string (e.g. (11, 2222) and (111, 222))
I added readonly to your fields. This would be critical if you decide to make the type a struct (i.e. even if you don't override the methods). But even for a class, mutable types that are equatable are a huge problem, because if they change after they are added to a hash-based collection, the collection is effectively corrupted. Using readonly here ensures that the type is immutable. (Also, IMHO public fields should be avoided, but if one must have them, they should definitely be readonly even if you don't override the equality methods).
Some people prefer to check for exact type equality in the Equals() method. In fact, this is often a good idea…it simplifies the scenarios where objects are compared and makes the code more maintainable. But for the sake of example, assignability (i.e. as) is easier to read, and is valid in many scenarios anyway.
See General advice and guidelines on how to properly override object.GetHashCode() for additional guidance.

Multiple Type Variable C#

I have a bit of a strange issue here. I have a project constraint where a value of a Property needs to either be a number (int, double, long, etc are all acceptable), a string, or a datetime. The reason that the Value parameter needs to be of one these three (err..well if you count all of the possible numeric value Types allowed it's a bit more) Types is because depending on the type the underlying value will need to be converted to special formats for serialization to a REST API. To simplify things here is a basic idea of the class as a POCO:
class Foo
{
public string Name {get;set;}
public Guid Id {get; set;}
public UNKNOWN Value {get;set;}
}
I thought about using generics for this, with a where T : struct constraint, but this still leaves too many types that can theoretically be set that are actually invalid Types. Sure I can perform type checking and throw exceptions during construction/setting of the Value parameter, but this doesn't feel like "clean" code.
I took a look at this question How do you work with a variable that can be of multiple types? , but it didn't really help since it was more of an issue dealing with inheritance. However, using multiple nullable private fields and returning a single Property based on which one was populated is a possibility, but again I feel there has to be a better way.
The other possibility I was thinking of was to use the dynamic type and and perform some reflection magic to check the underlying type (and perform conversions & formatting/throw exceptions). I'm a bit scared that this will really hurt performance though.
Are there any best practices for this situation? If not, are there any better ways to handle this from what I've mentioned?
EDIT Eric Lippert taught me this type of dispatch in one of his epic stackoverflow answers, and I'm searching for it at the moment. I will update this answer with a link if/when I track it down (the man has answered quite a few questions). Also, OP, you asked about performance, take a gander at this info also from Lippert: How does having a dynamic variable affect performance?
I would use a mix of dynamic with special case handling, and a generic type catch all for undefined (not yet implemented) types.
class Foo
{
public dynamic Value { get; set; }
}
class FooHandler
{
public void Serialize(Foo foo)
{
SerializeField(foo.Value);
}
void SerializeField(int field)
{
Console.WriteLine("handle int");
}
void SerializeField<T>(T field)
{
throw new NotImplementedException("Serialization not implemented for type: " + typeof(T));
}
}
class Program
{
[STAThread]
static void Main(string[] args)
{
Foo f = new Foo();
f.Value = 1;
FooHandler handler = new FooHandler();
handler.Serialize(f);
Console.ReadKey();
}
}
And then add types at your leisure.
You could use a dedicated class as a "multiple type variable".
At instantiation time you can pass an int, double, long, etc. and when you need to get the stored value out you can use a separate call.
public class Foo
{
public class Value
{
object _value;
public Value(int value) { _value = value; }
public Value(double value) { _value = value; }
public Value(long value) { _value = value; }
// etc
public object GetValue() { return _value; }
}
public void TestCall()
{
Value myValue = new Value(123);
Debug.WriteLine(myValue.GetValue());
}
}

Using Enums that are in an external dll

I have a project I am working that will involve creating one DLL that will be used across multiple other sites. Inside this DLL we need to reference about 10 Enums. The values of these Enums however will be different for each site the DLL is used on. For example:
MyBase.dll may have a class MyClass with an attribute of type MyEnum.
MyBase.dll is then referenced in MySite. MyStie will also reference MyEnums.dll which will contain the values for the MyEnum type.
Is there any way to accomplish this? While building MyBase.dll, I know what enums will exist in side of MyEnums.dll. The problem is I cannot build MyBase.dll without specifically referenceing the MyEnums.dll, which is not created until the MyBase.dll is used in a specific project.
I hope that makes sense and hope I can find an answer here.
Thanks.
Edit:
Thanks for all the comments. It will take a few reads to completely understand, but let me try to give a better example of what I am looking at here.
Lets say the following code is in my DLL that will be put into various projects. Status is an enum.
public Class MyClass
{
private Status _currentStatus;
public Status CurrentStatus
{
get
{
return _currentStatus;
}
}
public void ChangeStatus(Status newStatus)
{
_currentStatus = newStatus;
}
}
What I want to be able to do is the define the possible values for Status in the individual projects. So in this DLL, I will never reference what values might be in the Status enum, I just have to know that it exists.
I hope that is a bit more clear on what I am trying to do.
If you want each client to see different enum values (in a different assembly version), then using an enum is a bad solution - changes will break client code...
Using an enum might work (as long as the enum names and assembly name are the same and the assembly isn't signed) - you could just swap the assembly. However, if a value is used anywhere in the code that isn't there at the end you'll end up with an exception. Also, you may have the explicitly number the values, to make sure different subsets of the values won't end up with the same number for different values or different numbers for the same value.
Instead consider using a dynamically built collection, e.g. a list, a dictionary or a database table. Or just give the same assembly with the same superset of enum values to everyone and let the users decide which values are relevant to them (perhaps use significant prefixes for values as a convention).
Or you could use a combination of the two...
Generate a different structure (different type name (or namespace) and assembly name) per site with different properties (according to site's profile) and one master structure for the service that accepts the structures. Have all the structures implement the same interface, which you expect to receive...
public interface IStatus
{
string GetKey();
}
public struct ClientXStatus : IStatus
{
private readonly string _key;
private ClientXStatus(string key)
{
_key = key;
}
// Don't forget default for structs is 0,
// therefore all structs should have a "0" property.
public ClientXStatus Default
{
get
{
return new ClientXStatus();
}
}
public ClientXStatus OptionB
{
get
{
return new ClientXStatus(10);
}
}
string IStatus.GetKey()
{
return _key;
}
public override bool Equals(object obj)
{
return (obj is IStatus) && ((IStatus)obj).GetKey() == _key;
}
public override int GetHashCode()
{
return _key.GetHashCode();
}
public static bool operator==(ClientXStatus x, IStatus y)
{
return x.Equals(y);
}
public static bool operator==(IStatus x, ClientXStatus y)
{
return y.Equals(x);
}
public static bool operator!=(ClientXStatus x, IStatus y)
{
return !x.Equals(y);
}
public static bool operator!=(IStatus x, ClientXStatus y)
{
return !y.Equals(x);
}
// Override Equals(), GetHashCode() and operators ==, !=
// So clients can compare structures to each other (to interface)
}
Use a master struct for the service:
public struct MasterStatus : IStatus
{
private readonly string _key;
private MasterStatus(string key)
{
_key = key;
}
// Don't forget default for structs is 0,
// therefore all structs should have a "0" property.
public MasterStatus Default
{
get
{
return new MasterStatus();
}
}
// You should have all the options here
public MasterStatus OptionB
{
get
{
return new MasterStatus(10);
}
}
// Here use implicit interface implementation instead of explicit implementation
public string GetKey()
{
return _key;
}
public static implicit operator MasterStatus(IStatus value)
{
return new MasterStatus(value.GetKey());
}
public static implicit operator string(MasterStatus value)
{
return new value._key;
}
// Don't forget to implement Equals, GetHashCode,
// == and != like in the client structures
}
Demo service code:
public void ServiceMethod(IStatus status)
{
switch (status.GetKey())
{
case (string)MasterStructA.OptionB:
DoSomething();
}
}
Or:
public void ChangeStatus(IStatus status)
{
_status = (MasterStatus)status;
}
This way you:
Use code generation to prevent collision of values.
Force users to use compile time checks (no int values or string values) by hiding values (as private) and only accepting your structures.
Use real polymorphism in the service's code (an interface) and not a error-prone hack.
Use immutable value types (like enums) and not reference types.
First you have to decide WHERE to put your constants. Then you can transform your enum to static properties.
For example:
public enum MyEnum
{
Value1,
Value2
}
Can be changed to (first naive approach):
public static class MyFakeEnum
{
public static int Value1
{
get { return GetActualValue("Value1"); }
}
public static int Value2
{
get { return GetActualValue("Value2"); }
}
private static int GetActualValue(string name)
{
// Put here the code to read the actual value
// from your favorite source. It can be a database, a configuration
// file, the registry or whatever else. Consider to cache the result.
}
}
This simply will provide required constants but you'll have to throw away compile-time check for the type if you'll need MyFakeEnum as parameter. For a better solution you can follow, for example, what Microsoft did (more or less) for System.Drawing.Color.
public sealed class MyFakeEnum
{
public static readonly MyFakeEnum Value1 = new MyFakeEnum("Value1");
public static readonly MyFakeEnum Value2 = new MyFakeEnum("Value2");
private MyFakeEnum(string name)
{
_name = name;
}
public static implicit operator int(MyFakeEnum value)
{
return GetActualValue(value._name);
}
private string _name;
}
Of course you should provide proper overides at least for Equals, GetHashCode and ToString.
Pro
It can be an upgrade from an existing enum. Code won't be breaked and you may just need to recompile.
You can use it as strongly typed parameter. For example: void DoSomething(MyFakeEnum value) is valid and callers can't pass something else (note that this is one of the reasons because enums are considered weak).
If you implement all the required operators you can use the normal syntax for comparison: value == MyFakeEnum::Value1.
With a little bit of code you may even implement the FlagsAttribute syntax.
You do not change the normal syntax of enums: MyFakeEnum.Value1.
You can implement any number of implicit/explicit conversion operators to/from your type and any conversion will be safe and checked in the point it's done (this is not true again with standard enums).
You do not have hard-coded strings that can be breaked by changes and won't be catched until they cause a run-time error (yes, run-time). Using, for example, a dictionary if you'll change the definitions then you'll have to search all your code for that string.
Cons
First implementation is longer because you have to write support code (but for any new value you'll simply add a new line).
Value list is fixed and must be known at compile time (this is not an issue if you're searching a replacement for an enum because it's fixed too).
With this solution you may save more or less the same syntax you had with standard enums.

Overloaded indexer with enum : impossible to use default indexer

Considering the following code:
namespace MyApp
{
using System;
using System.Collections.ObjectModel;
class Program
{
static void Main(string[] args)
{
var col = new MyCollection();
col.Add(new MyItem { Enum = MyEnum.Second });
col.Add(new MyItem { Enum = MyEnum.First });
var item = col[0];
Console.WriteLine("1) Null ? {0}", item == null);
item = col[MyEnum.Second];
Console.WriteLine("2) Null ? {0}", item == null);
Console.ReadKey();
}
}
class MyItem { public MyEnum Enum { get; set; } }
class MyCollection : Collection<MyItem>
{
public MyItem this[MyEnum val]
{
get
{
foreach (var item in this) { if (item.Enum == val) return item; }
return null;
}
}
}
enum MyEnum
{
Default = 0,
First,
Second
}
}
I was surprised to see the following result:
1) Null ? True
2) Null ? False
My first expectation was that because I was passing an int, the default indexer should be used, and the first call should have succeeded.
Instead, it seems that the overload expecting an enum is always called (even when casting 0 as int), and the test fails.
Can someone explain this behavior to me?
And give a workaround to maintain two indexers: one by index, and one for the enum?
EDIT : A workaround seems to be casting the collection as Collection, see this answer.
So:
Why does the compiler choose the most "complex" overload instead of the most obvious one (despite the fact it's an inherited one)? Is the indexer considered a native int method? (but without a warning on the fact that you hide the parent indexer)
Explanation
With this code we are facing two problems:
The 0 value is always convertible to any enum.
The runtime always starts by checking the bottom class before digging in inheritance, so the enum indexer is chosen.
For more precise (and better formulated) answers, see the following links:
original answer by James Michael Hare
sum up by Eric Lippert
The various answers here have sussed it out. To sum up and provide some links to explanatory material:
First, the literal zero is convertible to any enum type. The reason for this is because we want you to be able to initialize any "flags" enum to its zero value even if there is no zero enum value available. (If we had to do it all over again we'd probably not implement this feature; rather, we'd say to just use the default(MyEnum) expression if you want to do that.)
In fact, the constant, not just the literal constant zero is convertible to any enum type. This is for backwards compatibility with a historic compiler bug that is more expensive to fix than to enshrine.
For more details, see
http://blogs.msdn.com/b/ericlippert/archive/2006/03/28/the-root-of-all-evil-part-one.aspx
http://blogs.msdn.com/b/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx
That then establishes that your two indexers -- one which takes an int and one which takes an enum -- are both applicable candidates when passed the literal zero. The question then is which is the better candidate. The rule here is simple: if any candidate is applicable in a derived class then it is automatically better than any candidate in a base class. Therefore your enum indexer wins.
The reason for this somewhat counter-intuitive rule is twofold. First, it seems to make sense that the person who wrote the derived class has more information than the person who wrote the base class. They specialized the base class, after all, so it seems reasonable that you'd want to call the most specialized implementation possible when given a choice, even if it is not an exact match.
The second reason is that this choice mitigates the brittle base class problem. If you added an indexer to a base class that happened to be a better match than one on a derived class, it would be unexpected to users of the derived class that code that used to choose the derived class suddenly starts choosing the base class.
See
http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx
for more discussion of this issue.
As James correctly points out, if you make a new indexer on your class that takes an int then the overload resolution question becomes which is better: conversion from zero to enum, or conversion from zero to int. Since both indexers are on the same type and the latter is exact, it wins.
It seems that because the enum is int-compatible that it prefers to use the implicit conversion from enum to int and chooses the indexer that takes an enum defined in your class.
(UPDATE: The real cause turned out to be that it is preferring the implicit conversion from the const int of 0 to the enum over the super-class int indexer because both conversions are equal, so the former conversion is chosen since it is inside of the more derived type: MyCollection.)
I'm not sure why it does this, when there's clearly a public indexer with an int argument out there from Collection<T> -- a good question for Eric Lippert if he's watching this as he'd have a very definitive answer.
I did verify, though, that if you re-define the int indexer in your new class as follows, it will work:
public class MyCollection : Collection<MyItem>
{
public new MyItem this[int index]
{
// make sure we get Collection<T>'s indexer instead.
get { return base[index]; }
}
}
From the spec it looks like the literal 0 can always be implicitly converted to an enum:
13.1.3 Implicit enumeration conversions An implicit enumeration
conversion permits the decimal-integer-literal 0 to be converted to
any enum-type.
Thus, if you had called it as
int index = 0;
var item = col[index];
It would work because you are forcing it to choose the int indexer, or if you used a non-zero literal:
var item = col[1];
Console.WriteLine("1) Null ? {0}", item == null);
Would work since 1 cannot be implicitly converted to enum
It's still weird, i grant you considering the indexer from Collection<T> should be just as visible. But I'd say it looks like it sees the enum indexer in your subclass and knows that 0 can implicitly be converted to int and satisfy it and doesn't go up the class-hierarchy chain.
This seems to be supported by section 7.4.2 Overload Resolution in the specification, which states in part:
and methods in a base class are not candidates if any method in a
derived class is applicable
Which leads me to believe that since the subclass indexer works, it doesn't even check the base class.
In C#, the contant 0 is always implicitly convertible to any enum type. You have overloaded the indexer, so the compiler chooses the most specific overload. Note that this happens during compilation. So if you would write:
int x = 0;
var item = col[x];
Now the compiler doesn't infer that x is always equal to 0 on the second line, so it will choose the original this[int value] overload. (The compiler isn't very smart :-))
In early versions of C#, only a literal 0 would be implicitly casted to an enum type. Since version 3.0, all constant expressions that evaluate to 0 can implicitly be casted to an enum type. That's why even (int)0 is casted to an enum.
Update: Extra information about the overload resolution
I always thought that the overload resolution just looked at the method signatures, but it also seems to prefer methods in derived classes. Consider for example the following code:
public class Test
{
public void Print(int number)
{
Console.WriteLine("Number: " + number);
}
public void Print(Options option)
{
Console.WriteLine("Option: " + option);
}
}
public enum Options
{
A = 0,
B = 1
}
This will result in the following behavior:
t.Print(0); // "0"
t.Print(1); // "1"
t.Print(Options.A); // "A"
t.Print(Options.B); // "B"
However, if you create a base class and move the Print(int) overload to the base class, then the Print(Options) overload will have a higher preference:
public class TestBase
{
public void Print(int number)
{
Console.WriteLine("Number: " + number);
}
}
public class Test : TestBase
{
public void Print(Options option)
{
Console.WriteLine("Option: " + option);
}
}
Now the behavior is changed:
t.Print(0); // "A"
t.Print(1); // "1"
t.Print(Options.A); // "A"
t.Print(Options.B); // "B"

Categories