Am trying to try parse based on a condition between two enums, how do we do this?
bool _isEnum1 = true;
public enum _Enum1
{
value,
Text,
Image
}
public enum _Enum2
{
TextArea,
Button,
Label
}
var _enum = _isEnum1 ? Enum.TryParse("value", out _Enum1 _enum) : Enum.TryParse("TextArea", out _Enum2 _enum)
I want '_enum' to hold right enum type value. Is this possible? Any other alternative is also fine.
Well, you're trying to have the type being dynamically resolved at runtime. You either have to split your entire program flow
if(_isEnum1)
{
Enum1 e = (Enum1)Enum.Parse(typeof(Enum1), "value");
HandleEnum1(e);
}
else
{
Enum2 e = (Enum2)Enum.Parse(typeof(Enum2), "value");
HandleEnum2(e);
}
where HandleEnumX are strongly typed with EnumX, so that the compiler knows what's going on, or go completely crazy overboard and use dynamic
dynamic e;
if(_isEnum1)
{
e = (Enum1)Enum.Parse(typeof(Enum1), s);
}
else
{
e = (Enum2)Enum.Parse(typeof(Enum2), s);
}
// Now e is either Enum1 or Enum2, resolved at runtime.
However, this seems wildly overcomplicated and more of a thought experiment than real code you should be pushing to production. You should probably rethink your design of this part of the program. At the very least, you might want to wrap your enums in a class to allow a more flexible design.
As a side note - you're using TryParse but never testing the returned value, so I took the liberty of exchanging them to Parse.
Enum result;
if (this._isEnum1)
{
result = (_Enum1)Enum.Parse(typeof(_Enum1), "value");
}
else
{
result = (_Enum2)Enum.Parse(typeof(_Enum2), "TextArea");
}
Related
Im quite new to C# and was wondering if it's possible to pass something to a function which is undefined / different each time, like the example below ;
string stringexam = "string"
or
int intexam = 5;
or
bool exam = false;
etc..
Myfunction(stringexam);
Myfunction(intexam);
Myfunction(exam);
public static void MyFunction(accepteverything) {
//DO SOMETHING
}
How could something like this be achieved ?
I need this because then I could use something like this in my code :
MyFunction(1,"ok example 1");
MyFunction(2, 22);
MyFunction(3, false);
Then I could continue in the MyFunction :
MyFunction(int method, accepteverything?!)
{
if(method == 1) {
ContinueExample1(string accepteverything); // CALLS FUNCTION CONTINUEEXAMPLE1 WHICH NEEDS A STRING AS PARAMETER
}
if(method == 2) {
ContinueExample2(int accepteverything); // CALLS FUNCTION CONTINUEEXAMPLE2 WHICH NEEDS A INT AS PARAMETER
}
if(method == 3) {
ContinueExample3(bool accepteverything);
}
}
You can do it with method overloads, the same named function but with different parameter types.
void MyFunction(string accepteverything)
{
ContinueExample1(accepteverything);
}
void MyFunction(int accepteverything)
{
ContinueExample2(accepteverything);
}
void MyFunction(bool accepteverything)
{
ContinueExample3(accepteverything);
}
This lets you do
string stringexam = "string"
int intexam = 5;
bool exam = false;
MyFunction(stringexam);
MyFunction(intexam);
MyFunction(exam);
You can also use Generic functions. This avoids boxing/Unboxing too
public void MyFunction<T>(int method, T acceptEverything)
{
switch(method)
{
case 1: ContinueExample1(acceptEverything as string); //String parameter
break;
case 2: ContineExample2(Convert.ToInt32(acceptEverything)); //int parameter
break;
// etc.
}
}
Call like this
MyFunction(1,stringexam);
MyFunction(2,intexam);
If the behavior of the method is the same no matter what type is passed in, you could pretty easily make the method:
public void MyFunction(int method, object acceptEverything)
{
switch(method)
{
case 1: ContinueExample1(acceptEverything as string);
break;
case 2: ContineExample2(acceptEverything as int);
break;
// etc.
}
}
Unfortunately that is going to introduce a lot of boxing and unboxing.
Sure, you could. But you probably want to rethink the way you're going about things. Wanting to reduce the code you have to write is good.
Bill Gates — 'I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it.'
But it's not always necessary, and can introduce unneeded complexity to something that otherwise is simple and self-explanatory.
Think about what's going on in your code. You have an exam which you want to do something with. Presumably you're concerned that there might be more than one way to identify a given exam for different users. But, whatever it is you want to do is probably not going to change. So, let's attack from that angle: we need to be able to identify an exam given some unknown parameter.
public Exam FindExamFromAnything(object input)
{
int examID = 0;
if (int.TryParse(input.ToString(), out examID))
{
return GetExamFromID(examID);
}
else
{
return GetExamFromName(input.ToString());
}
}
public Exam GetExamFromID(int ID)
{
// get the Exam with the right ID from a database or something
}
public Exam GetExamFromName(string examName)
{
// get the Exam with the right name from a database
}
Now you've got a method that you can pass whatever, and you'll get back the thing you were looking for. Great!
Except... two years from now somebody has a list of students that took a given exam, and tries to use your method:
List<string> students = new List<string> {"Alice","Bob"};
var exam = FindExamFromAnything(students); // nope!
Doesn't work. But how would he know? There's nothing in the signature that specifies what to use as the object. Now he's got to locate your source code, or use trial and error, to figure out how to use your API. Your documentation might explain that it only takes an int or a string, but...
Instead, it's not really that much more work to write a second method. As Scott Chamberlain points out you can overload a method name to take different parameters. A better solution for this implementation is to get more specific; I'm partial to methods like above exposed, that is, expose your GetExamFromString and GetExamFromID and whatever else you need, so they are self explanatory.
I've got a enum type defined in my C# code that corresponds to all possible values for the NetConnectionStatus field in Win32_NetworkAdapter WMI table, as documented here.
The documentation shows that the integers 0 through 12 each have a unique status name, but then all integers between 13 and 65,535 are lumped into one bucket called "Other." So here's my code:
[Serializable]
public enum NetConnectionStatus
{
Disconnected = 0,
Connecting = 1,
Connected = 2,
Disconnecting = 3,
HardwareNotPresent = 4,
HardwareDisabled = 5,
HardwareMalfunction = 6,
MediaDisconnected = 7,
Authenticating = 8,
AuthenticationSucceeded = 9,
AuthenticationFailed = 10,
InvalidAddress = 11,
CredentialsRequired = 12,
Other
}
This works fine for the values that are not Other. For instance, I can do this:
var result = (NetConnectionStatus) 2;
Assert.AreEqual(NetConnectionStatus.Connected, result);
But for anything in that higher numeric range, it doesn't work so great. I would like it if I could do this:
var result = (NetConnectionStatus) 20;
Assert.AreEqual(NetConnectionStatus.Other, result);
But right now that result variable gets assigned the literal value 20 instead of Other. Is there some out-of-the-box way of accomplishing this, something akin to Parse() but for integers instead of strings, or perhaps some special attribute I'm unaware of? I would prefer to not write my own wrapper method for this if there is already a good way to accomplish this.
If you have a string value, then the closest thing I can think of is to use Enum.TryParse:
NetConnectionStatus result;
if (Enum.TryParse(stringValue, out result) == false)
result = NetConnectionStatus.Other;
For an integer value that you're casting, you can use:
result = (NetConnectionStatus)integerValue;
if (Enum.GetValues(typeof(NetConnectionStatus)).Contains(result) == false)
result = NetConnectionStatus.Other;
Not really ideal, but in C# enums aren't much more than fancy names for integral values, so it's valid to stuff an integer value not in the defined values of the enums into a value of that enum type.
This solution will handle negative numbers, or cases where you have gaps in your enum values more elegantly than doing numerical comparisons.
it would be nice but no. How about
var result = (NetConnectionStatus) 20;
Assert.IsTrue(result >= (int)NetConnectionStatus.Other);
.NET does not such thing as a "any other" enumeration value bucket. Technically, enumeration (enum) is a pretty set of named constants of some underlying type (which is one of following: sbyte, short, int, long and their unsigned counterparts). You can cast an enum value to/from a corresponding type without any losses, as in this example:
enum TestEnum:int // Explicitly stating a type.
{
OnlyElement=0
}
class Program
{
static void Main(string[] args)
{
// Console.WriteLine implicitly calls ToString of the TestEnum.OnlyElement.
Console.WriteLine("OnlyElement == {0}", TestEnum.OnlyElement);
//TestEnum.OnlyElement equals to 0, as demonstrated by this casting:
Console.WriteLine("(int)OnlyElement == {0}", (int)TestEnum.OnlyElement);
//We can do it in reverse...
Console.WriteLine("(TestEnum)0 == ",(TestEnum)0);
// But what happens when we try to cast a value, which is not
// representable by any of enum's named constants,
// into value of enum in question? No exception is thrown
// whatsoever: enum variable simply holds that value, and,
// having no named constant to associate it with, simply returns
// that value when attempting to "ToString"ify it:
Console.WriteLine("(TestEnum)5 == {0}", (TestEnum)5); //prints "(TestEnum)5 == 5".
Console.ReadKey();
}
}
I'd like to repeat it again, enum in .NET is simply a value of the underlying type with some nice decorations like overriden ToString method and flags checking (look here or here if you want to know more about flags). You cannot have an integer with only 14 values like "0..12 and everything else", and so you cannot have such enum. In your example, NetConnectionStatus.Other simply receives single literal value (I assume it would most probably be '13', as the next available positive value of underlying type - however it actually depends on the compiler) as any other enumeration constant would do if not specified explicitly - and, obviously, it does not become a bucket.
However, there are options to achieve simple equation checks for integers/bytes/shorts/longs - and enums alike. Consider this extension method:
static bool IsOther(this NetConnectionStatus A)
{
return (A < (NetConnectionStatus)0) || (A > (NetConnectionStatus)12);
}
Now you can have a simple assertion like this:
var result = (NetConnectionStatus)10;
Trace.Assert(result.IsOther()); //No assertion is triggered; result is NetConnectionStatus.AuthenticationFailed
and
var result = (NetConnectionStatus)20;
Trace.Assert(result.IsOther()); //Assertion failed; result is undefined!
(Of course you can replace IsOther method with IsNotOther, overload it and pretty much anything else you could do with a method.)
Now there is one more thing. Enum class itself contains a method called IsDefined, which allows you to avoid checks for specific enum's value boundaries (<0, >12), therefore preventing unwanted bugs in case enum values would ever be added/removed, at the small performance cost of unboxing and checking each value in enum for a match (I'm not sure how this works under the hood though, I hope these checks are optimized). So your method would look like this:
static bool IsOther(NetConnectionStatus A)
{
return !Enum.IsDefined(typeof(NetConnectionStatus), A);
}
(However, concluding from enum's name, it seems like you want to make a network application/server, and for these performance might be of very great importance - but most probably I'm just being paranoid and this will not be your application's bottleneck. Stability is much more of concern, and, unless you experience real troubles with performance, it is considered to be much better practice to enable as much stability&safety&portability as possible. Enum.IsDefined is much more understandable, portable and stable than the explicit boundaries checking.)
Hope that helps!
Thanks everyone for the replies. As confirmed by all of you, there is indeed no way to do this out-of-the-box. For the benefit of others I thought I'd post the (custom) code I ended up writing. I wrote an extension method that utilizes a custom attribute on the enum value that I called [CatchAll].
public class CatchAll : Attribute { }
public static class EnumExtensions
{
public static T ToEnum<T, U>(this U value) where T : struct, IConvertible where U : struct, IComparable, IConvertible, IFormattable, IComparable<U>, IEquatable<U>
{
var result = (T)Enum.ToObject(typeof(T), value);
var values = Enum.GetValues(typeof(T)).Cast<T>().ToList();
if (!values.Contains(result))
{
foreach (var enumVal in from enumVal in values
let info = typeof(T).GetField(enumVal.ToString())
let attrs = info.GetCustomAttributes(typeof(CatchAll), false)
where attrs.Length == 1
select enumVal)
{
result = enumVal;
break;
}
}
return result;
}
}
So then I just have to apply that [CatchAll] attribute to the Other value in the enum definition. Then I can do things like this:
int value = 13;
var result = value.ToEnum<NetConnectionStatus, int>();
Assert.AreEqual(NetConnectionStatus.Other, result);
And this:
ushort value = 20;
result = value.ToEnum<NetConnectionStatus, ushort>();
Assert.AreEqual(NetConnectionStatus.Other, result);
I have a problem with convertion types. My mainForm keeps variable in integer type. Also my form has propertyGrid where I realized property for field (like combobox) with Image & Text. And now I don't understand well how can I convert one type into another. First I need to convert data from int to myProp and then vice versa.
Here setup propertyGrid:
public dashPatternList DashPattern
{
get { return dashPattern; }
set { dashPattern = value; }
}
Here I tried to realize my problem with additional methods:
private dashPatternList dashIN(int dash)
{
dashPatternList ds = dashPatternList.pic0;
if (dash == 1) ds = dashPatternList.pic1;
if (dash == 2) ds = dashPatternList.pic2;
return ds;
}
private int dashOUT(dashPatternList dash)
{
int i = 0;
if (dash == dashPatternList.pic1) i = 1;
if (dash == dashPatternList.pic2) i = 2;
return i;
}
And call it:
pData.DashPattern = dashIN(dashPattern);
dashPattern = dashOUT(pData.DashPattern);
This method works, but maybe you suggest me more easy way.
You could keep the pictures in an array, so instead of dashIN(dash) you'd write dashIN[dash] (and you don't need to write the dashIN function). You just need to initialize it once with something like this:
DashPattern[] dashIN = new DashPattern[] {
dashPatternList.pic0, dashPatternList.pic1, dashPatternList.pic2 };
For the reverse, something like Array.IndexOf(dashIN,mypic) should work.
This way you replace code with data, which tends to be a good thing as it's usually easier to manage. For example now you only have to change one line if you want to change the list of dash patterns, instead of having to change the code in two functions earlier. Plus now it's impossible to make an error that would cause dashOUT(dashIN(dash))!=dash (as would happen if there's a wrong number in the code).
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?
I have a problem using a class of made of structures.
Here's the basic definition:
using System;
struct Real
{
public double real;
public Real(double real)
{
this.real = real;
}
}
class Record
{
public Real r;
public Record(double r)
{
this.r = new Real(r);
}
public void Test(double origval, double newval)
{
if (this.r.real == newval)
Console.WriteLine("r = newval-test passed\n");
else if (this.r.real == origval)
Console.WriteLine("r = origval-test failed\n");
else
Console.WriteLine("r = neither-test failed\n");
}
}
When I create a non-dynamic (static?) Record, setting the Real works.
When I create a dynamic Record, setting the real doesn't work.
When I create a dynamic Record, replacing the real works.
And here's the test program
class Program
{
static void Main(string[] args)
{
double origval = 8.0;
double newval = 5.0;
// THIS WORKS - create fixed type Record, print, change value, print
Record record1 = new Record(origval);
record1.r.real = newval; // change value ***
record1.Test(origval, newval);
// THIS DOESN'T WORK. change value is not making any change!
dynamic dynrecord2 = new Record(origval);
dynrecord2.r.real = newval; // change value
dynrecord2.Test(origval, newval);
// THIS WORKS - create dynamic type Record, print, change value, print
dynamic dynrecord3 = new Record(origval);
dynamic r = dynrecord3.r; // copy out value
r.real = newval; // change copy
dynrecord3.r = r; // copy in modified value
dynrecord3.Test(origval, newval);
}
}
And here's the output:
r = newval-test passed
r = origval-test failed
r = newval-test passed
When I change the struct Real to class Real, all three cases work.
So what's going on?
Thanks,
Max
dynamic is really a fancy word for object as far as the core CLI is concerned, so you are mutating a boxed copy. This is prone to craziness. Mutating a struct in the first place is really, really prone to error. I would simply make the struct immutable - otherwise you are going to get this over and over.
I dug a little deeper into this problem. Here's an answer from Mads Torgersen of Microsoft.
From Mads:
This is a little unfortunate but by design. In
dynrecord2.r.real = newval; // change value
The value of dynrecord2.r gets boxed, which means copied into its own heap object. That copy is the one getting modified, not the original that you subsequently test.
This is a consequence of the very “local” way in which C# dynamic works. Think about a statement like the above – there are two fundamental ways that we could attack that:
1) Realize at compile time that something dynamic is going on, and essentially move the whole statement to be bound at runtime
2) Bind individual operations at runtime when their constituents are dynamic, returning something dynamic that may in turn cause things to be bound at runtime
In C# we went with the latter, which is nicely compositional, and makes it easy to describe dynamic in terms of the type system, but has some drawbacks – such as boxing of resulting value types for instance.
So what you are seeing is a result of this design choice.
I took another look at the MSIL. It essentially takes
dynrecord2.r.real = newval;
and turns it into:
Real temp = dynrecord2.r;
temp.real = newval;
If dynrecord2.r is a class, it just copies the handle so the change affects the internal field. If dynrecord2.r is a struct, a copy is made, and the change doesn't affect the original.
I'll leave it up to the reader to decide if this is a bug or a feature.
Max
Make your struct immutable and you won't have problems.
struct Real
{
private double real;
public double Real{get{return real;}}
public Real(double real)
{
this.real = real;
}
}
Mutable structs can be useful in native interop or some high performance scenarios, but then you better know what you're doing.