I need to get values of my enum, so I am using following command:
Array a = Enum.GetValues(typeof(Typ));
However, typical expression
a[x]
does not work, why?
Thanks
Well, because Enum.GetValues is not generic.
If you write:
var a = Enum.GetValues(typeof(Typ));
Console.WriteLine(a.GetType());
You'll get: "Namespace.Typ[]". But because method is not generic, compiler can't change returning type basing on supplied type, so the method returns System.Array which is base type for arrays and you have to use type casts to downcast it to expected type, for example:
Typ[] a = (Typ[])Enum.GetValues(typeof(Typ));
The proper way in my opinion to do it is:
Array a = Enum.GetValues(typeof(Typ));
and then retrieve elements at positions by:
a.GetValue(elementsIndex);
I've used the following code to handle emums when converting a custom classes for DB SP params, works all the time.
public static object ParamValue<T>(Enum value)
{
if (value == null)
return System.DBNull.Value;
else
return (T)Enum.Parse(value.GetType(), value.ToString());
}
Based on OPs comments, he might not actually be interested in the values of the Enum, but instead of the names. The distinction can easily be confusing to beginners. Tip: When you ask questions involving an error (i.e. "does not work, why?"), then including the error message often helps.
If you are looking for the names in the Enum, try:
string[] names = Enum.GetNames(typeof(Typ));
Related
I have Generic list holding root objects means I have:
public class Component
{
}
public class DBComponent : Component
{
}
private List<Component> components;
I want to get a list with only the DBComponent references using Linq. means something like that :
List<DBComponent> dbComponents = components.FindAll(c => c is DBComponent);
However, it does not seems to work
Please can someone provide working Linq code?
Thanks
You're looking for
IEnumerable<DBComponent> dbComponents = components.OfType<DBComponent>();
List<DBComponent> dbComponents = components.OfType<DBComponent>().ToList();
May be something like this, even if your code seems to be valid one too.
var result = components.Where(c => (c as DBComponent)!=null)
components.OfType<DBComponent>();
You should use either OfType or Cast method. The key difference is that Cast throws an exception, if the Enumerable contains any element that cannot be cast to the target type. OfType doesn't throw this exception, but just skip elements of those types.
In different scenarios both these methods can be handy, so it's up to you to choose. If you want just to filter your Enumerable by some Type, OfType is what you need, I guess.
object[] objArray = new object[]{"blah", 4, "whatever"};
foreach(var value in objArray) vs. foreach(object value in objArray)
I'm curious as to what the difference is between those, other than var must remain its type after assigned. Is one better than the other? Thanks.
From a purely functional perspective, var is just a shortcut for object here, since objArray's elements are of declared type object.
Using object is a sign to whoever's reading the code that the items in the array are not known to be any type more specific than object. The use of var does not connote this. In the minimal case you posted, it really doesn't make any difference to the clarity of the program which one you use.
If, on the other hand, it is not immediately clear from the context what type of object you are working with, then it may be advantageous to explicitly declare the type. On the other hand, if the type of the elements of the collection you're iterating over is verbose and obtrusive, then it may be advantageous to use var, so that the reader's eyes will be drawn to the logic of the code rather than a mess of generic parameters.
The only difference between var and any other type is that you let the compiler determine the type.
there is no difference between those two, var would be object in this case.
In your example no. But,
When declaring objects you get:
Boxing and Unboxing
However. When using var, it is compiled exactly as if you specified the exact type name.
So var tempval = 5; is the same as int tempval = 5;
I don’t mean overloading. This might include new Types of classes which I haven’t created yet.
EDIT:
I want to create a method which will return a value of the type it gets as a parameter. I can get a parameter of type object, but I don’t want to return it that way and then cast, I want the return-value itself to be of the same type as the parameter.
You could use reflection:
var returnType = typeof(SomeClass).GetMethod("SomeMethodName").ReturnType;
You can create a generic method which returns a type to be determined. As long as you declare your new classes correctly then they should work.
There are a number of ways of doing this, a search for return generic type c# turns up several different techniques of varying complexity. Fundamentally you have:
public T DoStuff<T>()
{
...
}
however, the "..." is the bit that depends on your application.
Based on your updates, the method you want will be something like:
public T MyMethod<T>(T input)
{
// DoSomething
T result = default(T); // Create your instance of T here
return result;
}
Yes, it's called reflection.
This should answer your question: http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.returntype.aspx
You can use generic type and generic methods to do that
C# Generic Methods
(OK, I'll expose the depths of my ignorance here, please be gentle)
Background
I've got a method which looks (a bit) like this:
public void AddLink(Enum enumVal)
{
string identifier = m_EnumInterpreter(enumVal);
AddLink(identifier);
}
The EnumInterpreter is a Func<Enum, string> that is passed in when the parent class is created.
I'm using Enum because at this level it is 'none of my business'- I don't care which specific enum it is. The calling code just uses a (generated) enum to avoid magic strings.
Question
If the EnumInterpreter sends back an empty string, I'd like to throw an exception with the actual value of enumVal. I thought I would just be able to cast to int, but it the compiler won't have it. What am I doing wrong? (Please don't say 'everything').
System.Enum cannot be directly cast to Integer, but it does explicitly implement IConvertible, meaning you can use the following:
public void AddLink(Enum enumVal)
{
string identifier = m_EnumInterpreter(Convert.ToInt32(enumVal));
AddLink(identifier);
}
Keep in mind that if your Enum is actually using something other than an Integer (such as a float), you'll lose the non-integer data on conversion. Or obviously replace the Convert call with whatever you are converting from (if it's known)
No, you aren't able to cast it to an int because System.Enum is not an enum, it's just the base class for enums.
EDIT:
You can get the value as follows, but it is ugly:
int intVar = (int)enuYourEnum.GetType().GetField("value__").GetValue(objYourEnum);
try this..
m_EnumInterpreter((int) (object) enumVal);
Various things here:
1) the answer of Ryan looks ok, but... I would rather pass the Enum down to the enum interpreter, so that you can do the whole Convert.To... there. If you know that you are using ONLY integer based enums, the Convert.ToInt32() is just fine. Otherwise you may want to add by using either reflection or try/catch other conversions.
2) You may also consider using members of the Enum class, like .GetName(), .GetValue(), etc. since they deal directly with the defined names and values independent of the enum type.
3) technically I would not throw the exception outside the enum interpreter. If that condition is generally true, throw the exception from inside the enum interpreter, so that all uses of the class will benefit of the validation. Or you might end up duplicating code.
4) you seem to have an C++/MFC background judging from your variable naming. You might want to get into C# style naming conventions, it will ease your life when using/reading other peoples code and libraries. Check out MS's StyleCop for a good addin to help with naming.
I don't know whether to include this in my question, or as an answer. The problem is that it isn't THE answer, but it is the answer that works for me.
What I discovered, by chance while trying something else, is that if I just wodge it onto the end of a string, I get what I want:
throw new Exception("EnumInterpreter returns empty string for enumVal=" + enumVal);
//EnumInterpreter returns empty string for enumVal=3720116125
I actually simplified to int in my question, the real data type is uint (in this particular instance). Fortunately, given that I only actually wanted the string, I don't have to worry about that.
I'm not sure which of the three other answers is 'right', so vote away...
For me it was enough to cast to object first, since it's just a compilation error.
public static int AsInt(this Enum #this)
{
return (int)(object)#this;
}
I understand that this is probably not the solution to your exact problem, but I just want to post how I solved this for a particular API I was using.
int result = (int) (ActualEnumType) MethodThatReturnsSystemEnumType( arg1, arg2 );
Hopefully that will be of help to someone. Double cast FTW.
Why not parse the enum to a string and return the actual enum value?
public enum MyEnum { Flower = 1, Tree = 2, Animal = 3 };
string name = MyEnum.Flower.ToString(); // returns "Flower"
I think .ToString() is deprecated and I'm not sure about the new way to do it. I would've thought the actual enum representation would be more useful than the int?
Id' like to create a list of data that will be passed from method to method, however I can't use a struct because the data that will be contained in this list will vary depending on the input.
For example
if (x == 1) {
a = 1
b = true
c = 42
d = "hello"
}
if (x == 2) {
a = 2
b = 'g'
c = "sup"
}
I believe my options are thus:
Create an array or List of strings, and cast the data back to what it originally was from strings. This is messy and could lead to bugs of uninterpretable input, though wouldn't be so bad since it'd all be detected at runtime.
Create a struct for each possibility - Is this even good practice?
Somehow use generics. From what I know, while generics are type-safe yet not type-strict, they must be cast to types before being used. Eg if I wanted a List of items here, I'd need to cast them to strings much like would happen with solution 1, making this useless.
My question then, is which of these options is the best? Or is there an alternate option using some sort of generic type I don't know about? The number of possible variables in each case may change, as with their types. I'd like to be able to return a single List or Array to the calling method, so that it may appropriately deal with the result. It will know how to deal with each group of data based on the value of a, as it will be the 'action choice' identifier. I'm also aware that casting them to objects and back each time is very intensive so I'd rather avoid that.
This is probably pretty simple but it has me stumped...
Since you don't know before hand what the list will contain, it looks like a good case for using an ArrayList.
If you want to get back to the values using a key, consider using a Hashtable.
The general principal in .NET is that every type can be cast to System.Object (although it may involve boxing). You can use a method like
void Foo(params object[] parameters) { ... }
Or use the System.Collections.ArrayList class.
The 'problem' is that when you want to use such a value, you will need code like:
if (parameters[i] is string)
{
string s = (string) parameters[i];
...
}
Sorry, this is not a code related answer: there may be a faulty design hidden behind such a construct. Make sure you know what you are doing, otherwise things might fire back.
If not knowing the type of the fields you use beforehand really is required, this calls for an approach that saves the data with their type, like
struct foo {
private object _value;
private string _type;
foo(string myType, object myValue) {
_value = myValue;
_type = myType;
}
}
and then using Generics to handle the business logic.
Basically you need a list typed to Object, and then yes, you're in a mode of casting back.
My question is, structurally, how will you know what indexes are of which type? This sounds like a painful solution at best.
If you really need to store differing types in the list, perhaps try a struct which contains a member of each type, as well as a flag indicating which data type is represented. Then use a generic collection for that struct. Something like (off the top of my head)
struct FooType
{
public string StringValue;
public bool BoolValue;
public int IntValue;
public char CharValue;
public string DataType;
// You'd probably want constructors too
}
Then the generic list:
var values = new List<FooType>();
Now you can add and remove entries in the list using that type, which would then indicate what the core data really is.
I still don't like the answer; it sounds like your design may be trying to do too much and there may be refactoring opportunities, but since I don't see much more of your code or intent, all I can do is answer what you've asked. :)
You could represent the data items using a Dictionary/Hashtable and then add these dictionaries to a List.
You could also add extra type information into the dictionary value if needed.