0

Due to the question here is marked as duplicated, so here I repeat the question and make more explanation about the question. Hope someone can give some suggestions. =======================================

As described in the question, here is a enum:

public enum MyEnum {  One,  Two,  Three}

is going to be parsed based on mutl strings.For example, below strings are all going to be parsed as MyEnum.Two:

"Two", "TWO", "Second", "2"

The reason that I can't leverage the description attributes or a mapping dictionary directly is that the mapping strings come from an external xml file. The mapping will change after a period of time and so that It's not possible just adding the description attribute with the above declared enum.

For example, the mappings above was build one month ago and now there are some extra items required as below and these new items will be just add to the xml file:

"2nd", "The Second one"

Furthermore, I use a self developed script engine to parse above and other similar needs (that's why I don't use a simple mapping function) :

Object x = engine.Execute( /*some script codes defined in external xml*/ );
if (ReturnType.IsEnum && Enum.IsDefined(ReturnType, x)) //ReturnType is defined in external xml file
    return Enum.Parse(ReturnType, x.ToString());
else if (ReturnType.IsEnum)
{
    // Hope I can handle Extra mapping here
}
else
    return Convert.ChangeType(x, ReturnType);

It seems very strange to just pass-in a mapping table to the above codes because it was designed for generic script executing purpose. So I think @xanatos (in the prevous 'duplicated' question) gave a way to resolve this issue, but the mapping (via customized attributes) should be generated at runtime. Attributes seems a meta data and can't be changed after compilation, however, I found some posts say that I can use TypeDescriptor to add attributes at runtime, is it possible? and How?

Community
  • 1
  • 1
jones
  • 317
  • 3
  • 13
  • 3
    I've re-opened your other question as it is not a duplicate. I suggest you edit that question to include more detail from here and then DELETE this question. – Enigmativity Jun 01 '15 at 10:10
  • You can use custom attributes if the mapping does not change in the future. It is possible to change the attribute value for an instance as described in this link http://stackoverflow.com/a/51282/1305119. But it only changes the attribute value for that instance, see http://stackoverflow.com/a/10047350/1305119. You need to repeat this for all instances. In my opinion, using custom attributes for your case is not correct way. – Suresh Kumar Veluswamy Jun 01 '15 at 10:18
  • A Better way is to use a dictionary with the key as string and value as the enum. You can populate this dictionary after reading from the external xml file. When you want to parse a string, you can retrieve the enum value from the dictionary. The only problem here is the strings used as key for the dictionary are case sensitive. – Suresh Kumar Veluswamy Jun 01 '15 at 10:29
  • I suggest you add the information about the external file to your original question. This converts a parsing problem to an ETL/integration problem - you *have* to clean external data before you attempt to parse them. In such cases, any required mappings or replacements should be placed in lookup tables or files, so you can modify them whenever the input changes – Panagiotis Kanavos Jun 01 '15 at 10:40

1 Answers1

0

The fact that the data comes from an external file whose contents change, makes this an ETL/integration problem. In such cases you have to put a cleanup/normalization step before actually parsing the data.

In such cases, the typical solution is to create lookup tables that map inputs to recognized outputs and replace the input with the lookup values before parsing. In fact, ETL tools like SQL Server's Integration Services include Lookup transformations for exactly this purpose.

Once you replace your incoming data with the lookup data, you can parse it using
Enum.TryParse (String, Boolean) or Enum.TryParse(String, Boolean, TEnum). Both methods allow you to parse the input in a case-insensitive manner and parse both values or names.

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236