I have a enum type (i.e. View). I would like to extract a part of this enum [Top,Bottom,Left,Right,Front,Rear] to add in to a combo box as ComboBox.DataSource = Enum.GetValues(typeof(View_extracted)).
Is it possible?
enum View {Top,Bottom,Left,Right,Front,Rear,Trimetric,Isometric,Diametric}
View_extracted should contain first 6 values only:
{Top,Bottom,Left,Right,Front,Rear}
LINQ to the rescue!
Enum.GetValues(typeof(View)).Cast<View>().Take(6);
If you wanted it to be a proper enum, you can mess around with ILGen but it's way, way more trouble than it's worth.
No, it's strictly not possible to create a type View_extracted, that would be able to be called using that exact code to create the stated results.
While you could create another enum that had values that happened to have the same names as this other enum, and you could create a method (that would have to be different than what you described) to get at a list of this enum's values, it's a very brittle system.
What I would suggest doing, instead of creating a new enum as a view, is to simply create a new method as a view that returns the values of this enum, something like:
public static IEnumerable<View> ExtractedView()
{
//return a sequence of the views here, whether it be a hard code list,
// or a filtered result of a call to Enum.GetValues, or whatever
}
Related
I have an AnonymousType object that contacts two fields with their values. How can I access the value of these fields?
Ex:
SourceTypeObject { Source_Type_Id = 1, Source_Type_Name = "bibliography" }
I need to do something like : SourceTypeObject.Source_Type_Id
Is that possible?
EDIT:
Here's what I get if I tried to access the property directly:
Yes, this is the exact purpose of anonymous types. The only thing that might prevent you from doing so is if you passed the anonymous type around as a parameter with type "object". This would hide information about the anonymous type, and it would look like just any old object then.
The only recourse if this is the case is to use reflection, which is slow and awkward. Anonymous types are a meant to be a very "local" phenomenon, and if you find yourself wanting to use them elsewhere in the program, it's worth the time to promote it to a real type.
EDIT: In response to the image you posted, assuming the array is declared locally just outside of view, try to replace the object SourceTypeObject with var SourceTypeObject. This allows it to infer the anonymous type instead of being told that it's an object.
I expect the following call to the Parse method to return the enum member EN_CA but it returns EN instead.
Enum.Parse(LanguageType, "EN_CA", true);
where:
enum LanguageType
{
EN = 0,
EN_CA = 0,
FR = 1
}
It seems like the Parse method just grabs the first member that maps to the value of the parameter that is passed into it.The Parse method seems to be loosing information during the conversion from string to enum member. Changing the order of EN_CA and EN would make the above call to return EN_CA but that is not going to solve the problem since it would cause a similar issue when calling the method for "EN".
Additional context related information: In my code, the LanguageType Enum is represent the index for a dictionary and these indices are used for localizing the language.
Does anyone have any idea of how to map two enum member to the same value while being able to get proper member from Enum.Parse? Do I just need to implement my own version of Enum.Parse which doesn't collapse the members with the same value into one?
An enum member is distinct from other enum members if and only if it has a different value. Effectively the members of the enumeration are named constants, with no real distinction between them other than the value they hold.
In your LanguageType enum you have two labels for the same value, and no way to distinguish them. Try this:
Console.WriteLine("{0} == {1} ? {2}",
LanguageType.EN.ToString(),
LanguageType.EN_CA.ToString(),
LanguageType.EN == LanguageType.EN_CA);
The output is:
EN == EN ? True
The same thing happens when you assign LanguageType.EN_CA to a variable, then examine the variable later to see what it contains. What you get is LanguageType.EN.
The key here is that the value of the member is all-important in most instances, with the position of the member being the tie-breaker during collisions. When two members have the same value the member that is declared first is the one that you will see whenever you do string conversions, including when you examine the value in the IDE.
So in effect you have a value LanguageType.EN_CA that is only an alias to the value LanguageType.EN.
While I can think of a couple of cute uses for this - like parsing incoming data that has multiple representations for the same value - it is really quite a terrible thing to do in most real-world environments, especially if you want to be able to do fully symmetric serialization/deserialization.
Now, as to your localization Dictionary...
It costs very little to store the same class object multiple times in a Dictionary, since class objects are stored by reference. Assuming you have a Localization class, the following code is not particularly inefficient in terms of storage:
enum LanguageType
{
EN, EN_CA, EN_US, EN_GB, EN_AU, FR
}
Dictionary<LanguageType, Localization> localizations = new Dictionary<LanguageType, Localization>();
localizations[LanguageType.EN] = new Localization("EN");
localizations[LanguageType.EN_CA] = localizations[LanguageType.EN];
localizations[LanguageType.EN_US] = localizations[LanguageType.EN];
localizations[LanguageType.EN_GB] = localizations[LanguageType.EN];
localizations[LanguageType.EN_AU] = localizations[LanguageType.EN];
Even if the Localization object contains a huge collection of resources, the above code only ever creates one instance of it. You get distinct values for the LanguageType members, and the Dictionary does the mappings for you.
You defined 0 twice in your enum - this will not work. Each value has to be unique or how else would an enum recognize its values - it is actually stored as integer.
Change it to:
enum LanguageType
{
EN = 0,
EN_CA = 1,
FR = 2
}
EDIT:
As pointed out by Greenish, you can define multiple names for the same value which acts as a sort of an alias. Using both or multiple names return the same value. If you try to get the string value from an integer value, you will get the first value defined for that integer.
In your case, you cannot achieve what you need using enums. You should probably build your own custom class to achieve that.
Enums basically are named integers. And it is possible to assign different names for a single number (as in your example for 0).
Enum.Parse searching for a first correct instance - and here you have a valid name as 0 == 0. So the solution is to change your numbers (or even just get rid of them as they are 0, 1, 2)
enum LanguageType
{
EN,
EN_CA,
FR
}
I thought of a way but it's messy fragile and naff. There again it illustrates the hole you have dug for yourself..
int index = Enum.GetNames(typeof(LanguageType)).indexof("EN_CA")
will give you 1
then something like
switch(index)
{
case 0 : return LanguageType.EN;
case 1 : return LangaugeType.EN_CA;
case 2 : return LanguageType.FR;
default : // throw some useful exception maybe
break
}
will return the member you want.
Horrible isn't it?
Enum.GetValues(typeof(LanguageType)) would return [0,0,1] and using indexof 0 on it is of course 0, which is why Parse is giving you the result it is.
The =0 specifies the representation of the enum's value in the underlying type (int). You've given both EN and EN_CA the same representation, namely 0, so now they've effectively become two labels for the same value.
Enum.Parse returns this value and it'll equal both labels.
The underlying problem is that you're trying to code a hierarchical concept, into a flat enum. For some purposes all english speaking cultures should be treated equal, for other purposes you'd like to distinguish between them.
The solution, I think, is to use the already present mechanisms for localizing your application, in particular CultureInfo should replace your enum and Resources your lookup dictionary.
I was a little surprised that this use of enum is allowed :)
But the MSDN documentation explicitly states it is valid and gives an example of how it can be useful:
enum Color
{
Red,
Green,
Blue,
Max = Blue
}
So here is how I fixed my problem:
I was not able to find a clean fix for the problem by getting Enum.Parse method return what I was expecting it to.(please see the note*)
My fix was to apply GroupBy(LanguageIndex) on the resulting dictionary which had its index duplicated and therefore throwing an exception. Since I wanted EN_CA and EN to have the same value in the enum that gave me what I was looking for without throwing an exception.
I can see that my fix is not an actual answer to the question that I initially asked, ignoring the context; though I though it might still be applicable to other contexts with a similar issue.
note* : I could have implemented my own version of Enum.Parse - Please see this answer for an alternative implementation - but that required me to put smelly hardcoded stuff into my code, so I just gave up on fixing the Parse method.
I have a dbf file (dBase) that I want to read, put each row into a single list (since a row represents data about one shapefile object), and then be able to modify the list (e.g., convert fields which represent the name to a string). This means that the datatype need to be able to hold both Ints, strings, bool and so on, and add items to, it. In python I could do this with lists, but since sets cant be modified, I cant use them.
This sounds like a (exact) duplicate to Alternative to Tuples,
but it isn't. These questions are based on the assumption that you know which objects you want beforehand; I don't.
I'm on .NET 4.5, btw.
Use dynamic - it is a perfect use case for it:
Visual C# 2010 introduces a new type, dynamic. The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object. At compile time, an element that is typed as dynamic is assumed to support any operation. Therefore, you do not have to be concerned about whether the object gets its value from a COM API, from a dynamic language such as IronPython, from the HTML Document Object Model (DOM), from reflection, or from somewhere else in the program. However, if the code is not valid, errors are caught at run time.
If you want to be able to easily add properties at runtime and change their types, you can use ExpandoObject with dynamic, for example:
dynamic expando = new ExpandoObject();
expando.SomeProperty = "1234";
Console.WriteLine(expando.SomeProperty);
Console.WriteLine(expando.SomeProperty.GetType().FullName); // string
expando.SomeProperty = int.Parse(expando.SomeProperty);
Console.WriteLine(expando.SomeProperty);
Console.WriteLine(expando.SomeProperty.GetType().FullName); // int
Have you tried using the dynamic type?
Ok here is my dilemma, I want to create an array of custom objects but then be able to do something like list[index].method call.
as an example:
program starts
program creates a master array which holds GenericClass< T >(param)
each generic class then creates an array of type T
I can get that part to work ok but then when I try to use my object methods such as
object[] MasterList = new object[MASTER_LIST_SIZE];
// add contents to MasterList
MasterList[index].setValueAt(MethodIndex, value);
I get a message that reads object has no method named setValueAt which requires one parameter(s)
I will admit that what I am trying to do is rather dumb and I could probably do it easier with reading a text file or something but if there is a way to do it like this I would like to know how or at least what I am missing.
There are a lot of unknowns about what you are doing but my best guess is that you need to cast the result to the type you need.
((GenericClass<T>)MasterList[index]).setValueAt(MethodIndex, value);
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.