I have an enum like this:
enum myEnum
{
a = 0101,
b = 2002,
c = 0303
}
I try to get enum value with casting but the 0 at the begin of my enums was removed.
For example I tried this:
var val = (int)myEnum.a;
How can get enum value as string when we have 0 at the beginning of it?
You should rethink your design, but if you want to check your enum integers to a given string, you can use .ToString("0000") to get the string "0101" out of the integer 101.
First, enums are integers, since as their name says, they are enumerations and an enumeration, they are numbers, so enum is integer.
Secondly, you must bear in mind that zero is a null value, since the system is a 01 or 001 like 1, since (basic mathematics) a zero to the left is worthless, so this code is incorrect.
enum myEnum
{
a=0101,
b=2002,
c=0303,
}
The correct way is
enum myEnum
{
a = 0,
b = 1,
c = 2
}
Where the zero is alone, so the system sees it as an index
Now with this, you should only use one of the conversion processes of C#
string strOne = ((myEnum)0).ToString();
string strTwo = ((myEnum)1).ToString();
string strThree = ((myEnum)2).ToString();
Read the MSDN reference https://msdn.microsoft.com/en-us/library/16c1xs4z(v=vs.110).aspx
Enumeration values are always integers. If you need to associate a string with an enumeration value, you can use a dictionary:
enum myEnum { a, b, c }
Dictionary<myEnum, string> lookup = new Dictionary
{
{ a, "0101" },
{ b, "2002" },
{ c, "0303" }
};
To get the string associated with a particular value just use this:
var s = lookup[myEnum.a]; // s = 0101
Another common way to handle this sort of problem is simply to use constants.
class MyConstants
{
public const string a = "0101";
public const string b = "2002";
public const string c = "0303";
}
var s = MyConstants.a; // s = 0101
Try using formatting: you want 4 digits and that's why you can put d4 format string. In order to hide all these implmentation details (cast and formatting) let's write an extension method:
enum myEnum {
a = 0101,
b = 2002,
c = 0303
}
static class myEnumExtensions {
public static string ToReport(this myEnum value) {
return ((int)value).ToString("d4"); // 4 digits, i.e. "101" -> "0101"
}
}
...
myEnum test = myEnum.a;
Console.Write(test.ToReport());
If you always need a specific number of digits you could use string format to get the leading zeros:
var str = String.Format("{0:0000}", (int)myEnum.a);
Or, shorter:
var str = $"{(int) myEnum.a:D4}";
Alternative:
Use an attribute to add extra information to an enum
Attribute:
public class DescriptionAttribute : Attribute
{
public string Name { get; }
public DescriptionAttribute(string name)
{
Name = name;
}
}
Enum:
enum myEnum
{
[Description("0101")]
a = 101,
[Description("2002")]
b = 2002,
[Description("303")]
c = 303
}
Extension Method:
public static string GetDescription(this myEnum e)
{
var fieldInfo = e.GetType().GetField(e.ToString());
var attribute = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute;
return attribute.Name;
}
Usage:
var name = myEnum.a.GetDescription() //will return '0101'
Assuming that the numbers in your enum always have a length of 4
you can use the following
var val = (int)myEnum.a).ToString().PadLeft(4, '0')
in the code below calling SequenceEqual on generic list return true (as expected) when List is defined with class generic type (EquatableClass.Equals<> is called).
If list is defined with IEquatable interface, Equals method is not called and result is false (object.Equals is called instead, not in code).
The question is, why the EquatableClass.Equals<> method is not called in the second case?
public class EquatableClass : IEquatable<EquatableClass>
{
public string Name { get; set; }
public bool Equals(EquatableClass other) => this.Name.Equals(other.Name);
}
static void Main(string[] args)
{
var A = new List<EquatableClass> { new EquatableClass { Name = "A" } };
var B = new List<EquatableClass> { new EquatableClass { Name = "A" } };
var result1 = A.SequenceEqual(B); // == true;
var AA = new List<IEquatable<EquatableClass>> { new EquatableClass { Name = "A" } };
var BB = new List<IEquatable<EquatableClass>> { new EquatableClass { Name = "A" } };
var result2 = AA.SequenceEqual(BB); // == false;
}
The SequenceEqual<T> method will try to see if it can convert T to IEquatable<T>, and if it can, it will use IEquatable<T>.Equals for equality.
When you have a List<EquatableClass> it will then try to convert EquatableClass to IEquatable<EquatableClass>, and that succeeds, so it uses the appropriate Equals method.
When you have a List<IEquatable<EquatableClass>> it will then try to convert IEquatable<EquatableClass> to IEquatable<IEquatable<EquatableClass>>, and that will fail, because the actual object doesn't implement IEquatable<IEquatable<EquatableClass>>, so it resorts to the default behavior of using object.Equals(object), which you don't override.
Maybe it is silly question, but I am quite new in C#. I have such a object:
MyStructure data = new MyStructure()
{
Name = "Test",
DateTime = "2017-07-14T00:00:00.000Z",
Items = new List<ItemsRequest>
{
new ItemsRequest() { Type = ItemsType.Green, Id = "0020012321" }
}
};
And I have method where I am validating such structure:
var badRequests = new Dictionary<Func<bool>, string>
{
[() => myStructure.Name == null] = "Name parameter cannot be empty or null string",
[() => (myStructure.ItemsRequest[0].Type == ItemsType.Green &&
myStructure.ItemsRequest[0].Id == myStructure.ItemsRequest[0].Id && yStructure.ItemsRequest[1].Type == ItemsType.Red &&
myStructure.ItemsRequest[1].Id == myStructure.ItemsRequest[1].Id)] = "could not be created with one with these types",
};
This validation DO NOT pass, because there aren't 2 items in my object, but I am getting such a error:
An exception of type 'System.ArgumentOutOfRangeException' occurred in
mscorlib.dll but was not handled in user code
Additional information: Index was out of range. Must be non-negative
and less than the size of the collection.
How can I handle it when I have only one item in list and do not get error? As I understand it is because of indexes [] .
Edit: When I have such a structure with one item:
MyStructure data = new MyStructure()
{
Name = "Test",
DateTime = "2017-07-14T00:00:00.000Z",
Items = new List<ItemsRequest>
{
new ItemsRequest() { Type = ItemsType.Green, Id = "0020012321" }
}
};
And in dictionary I validate only this function, it pass succesfully, because I select only one item with specific entries.
[() => myStructure.ItemsRequest.Select(x => x.Type == ItemsType.Green && x.Id == "0020012321").FirstOrDefault()] = "Type cannot be Green",
But is there are any possibilities to be independent of indexes and select as many as you like items from object?
The following code has been tested and works fine, if this doesn't work (as you previously mentioned on a comment) then there must be something else wrong with your code.
I have changed the Dictionary<Func<bool>, string> to Dictionary<Predicate<MyStructure>, string>, Predicate<T> will return true or false based on your condition - and it will take a parameter of T, which in this case will be a parameter of type MyStructure - this allows you to define your collection outside of the method.
class Program
{
// Create a Dictionary of Key type Predicate<MyStructure>, Predicate returns true or false - no need for a Func<bool>
private static Dictionary<Predicate<MyStructure>, string> badRequests = new Dictionary<Predicate<MyStructure>, string>
{
[p => string.IsNullOrWhiteSpace(p.Name)] = "Name parameter cannot be empty or null string",
[p => p.Items.Count == 2 /* <- This is important, as René pointed out in his answer */ && p.Items[0].Type == ItemsType.Green &&
p.Items[0].Id == "0020012321" && p.Items[1].Type == ItemsType.Red &&
p.Items[1].Id == "9023546547"
] = "could not be created with one with these types"
};
static void Main(string[] args)
{
// Initialize object
MyStructure data = new MyStructure()
{
Name = "Test",
DateTime = "2017-07-14T00:00:00.000Z",
Items = new List<ItemsRequest>
{
new ItemsRequest() { Type = ItemsType.Green, Id = "0020012321" },
new ItemsRequest() { Type = ItemsType.Red, Id = "9023546547" }
}
};
// Call badRequests Dictionary with data to fetch Value
string myString = badRequests.FirstOrDefault(p => p.Key.Invoke(data)).Value;
Console.ReadKey();
}
public class MyStructure
{
public string Name { get; set; }
public string DateTime { get; set; }
public List<ItemsRequest> Items { get; set; }
}
public class ItemsRequest
{
public string Id { get; set; }
public ItemsType Type { get; set; }
}
public enum ItemsType
{
Green, Red
}
}
Simply add test the Count of the list before accessing:
() => (myStructure.ItemsRequest.Count == 2 && // <-- add this line
myStructure.ItemsRequest[0].Type == ItemsType.Green &&
myStructure.ItemsRequest[0].Id == "0020012321" &&
myStructure.ItemsRequest[1].Type == ItemsType.Red &&
myStructure.ItemsRequest[1].Id == "9023546547")
The expression is evaluated "short-circuited", so if Count is not 2, the rest of the expression is not evaluated and so you don't try to access index 1 of the list if there is no second element.
Can anyone help me with this?
Required Output: "Todo job for admin"
class Program
{
static void Main(string[] args)
{
Console.WriteLine(ReplaceMacro("{job.Name} job for admin", new Job { Id = 1, Name = "Todo", Description="Nothing" }));
Console.ReadLine();
}
static string ReplaceMacro(string value, Job job)
{
return value; //Output should be "Todo job for admin"
}
}
class Job
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Two suggestions:
DataBinder.Eval
string ReplaceMacro(string value, Job job)
{
return Regex.Replace(value, #"{(?<exp>[^}]+)}", match => {
return (System.Web.UI.DataBinder.Eval(new { Job = job }, match.Groups["exp"].Value) ?? "").ToString();
});
}
Linq.Expression
Use the Dynamic Query class provided in the MSDN LINQSamples:
string ReplaceMacro(string value, Job job)
{
return Regex.Replace(value, #"{(?<exp>[^}]+)}", match => {
var p = Expression.Parameter(typeof(Job), "job");
var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, match.Groups["exp"].Value);
return (e.Compile().DynamicInvoke(job) ?? "").ToString();
});
}
In my opinion, the Linq.Expression is more powerful, so if you trust the input string, you can do more interesting things, i.e.:
value = "{job.Name.ToUpper()} job for admin"
return = "TODO job for admin"
You can't use string interpolation this way. But you can still use the pre-C#6 way to do it using string.Format:
static void Main(string[] args)
{
Console.WriteLine(ReplaceMacro("{0} job for admin", new Job { Id = 1, Name = "Todo", Description = "Nothing" }));
Console.ReadLine();
}
static string ReplaceMacro(string value, Job job)
{
return string.Format(value, job.Name);
}
This generic solution Extend the answer provided by #Dan
It can be used for any typed object.
install System.Linq.Dynamic
Install-Package System.Linq.Dynamic -Version 1.0.7
string ReplaceMacro(string value, object #object)
{
return Regex.Replace(value, #"{(.+?)}",
match => {
var p = Expression.Parameter(#object.GetType(), #object.GetType().Name);
var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, match.Groups[1].Value);
return (e.Compile().DynamicInvoke(#object) ?? "").ToString();
});
}
See a working demo for a Customer type
You could use RazorEngine:
using RazorEngine;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(ReplaceMacro("#Model.Name job for admin", new Job { Id = 1, Name = "Todo", Description="Nothing" }));
Console.ReadLine();
}
static string ReplaceMacro(string value, Job job)
{
return Engine.Razor.RunCompile(value, "key", typeof(Job), job);
}
}
It even supports Anonymous Types and method calls:
string template = "Hello #Model.Name. Today is #Model.Date.ToString(\"MM/dd/yyyy\")";
var model = new { Name = "Matt", Date = DateTime.Now };
string result = Engine.Razor.RunCompile(template, "key", null, model);
Little late to the party! Here is the one I wrote -
using System.Reflection;
using System.Text.RegularExpressions;
public static class AmitFormat
{
//Regex to match keywords of the format {variable}
private static readonly Regex TextTemplateRegEx = new Regex(#"{(?<prop>\w+)}", RegexOptions.Compiled);
/// <summary>
/// Replaces all the items in the template string with format "{variable}" using the value from the data
/// </summary>
/// <param name="templateString">string template</param>
/// <param name="model">The data to fill into the template</param>
/// <returns></returns>
public static string FormatTemplate(this string templateString, object model)
{
if (model == null)
{
return templateString;
}
PropertyInfo[] properties = model.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
if (!properties.Any())
{
return templateString;
}
return TextTemplateRegEx.Replace(
templateString,
match =>
{
PropertyInfo property = properties.FirstOrDefault(propertyInfo =>
propertyInfo.Name.Equals(match.Groups["prop"].Value, StringComparison.OrdinalIgnoreCase));
if (property == null)
{
return string.Empty;
}
object value = property.GetValue(model, null);
return value == null ? string.Empty : value.ToString();
});
}
}
Example -
string format = "{foo} is a {bar} is a {baz} is a {qux} is a really big {fizzle}";
var data = new { foo = 123, bar = true, baz = "this is a test", qux = 123.45, fizzle = DateTime.UtcNow };
Compared with other implementations given by Phil Haack and here are the results for the above example -
AmitFormat took 0.03732 ms
Hanselformat took 0.09482 ms
OskarFormat took 0.1294 ms
JamesFormat took 0.07936 ms
HenriFormat took 0.05024 ms
HaackFormat took 0.05914 ms
Wrap the string in a function...
var f = x => $"Hi {x}";
f("Mum!");
//... Hi Mum!
You need named string format replacement. See Phil Haack's post from years ago: http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases.aspx/
Not exactly but with bit tweek, I have created generic interpolation which support fields / property only.
public static string Interpolate(this string template, params Expression<Func<object, string>>[] values)
{
string result = template;
values.ToList().ForEach(x =>
{
MemberExpression member = x.Body as MemberExpression;
string oldValue = $"{{{member.Member.Name}}}";
string newValue = x.Compile().Invoke(null).ToString();
result = result.Replace(oldValue, newValue);
}
);
return result;
}
Test case
string jobStr = "{Name} job for admin";
var d = new { Id = 1, Name = "Todo", Description = "Nothing" };
var result = jobStr.Interpolate(x => d.Name);
Another
string sourceString = "I wanted abc as {abc} and {dateTime} and {now}";
var abc = "abcIsABC";
var dateTime = DateTime.Now.Ticks.ToString();
var now = DateTime.Now.ToString();
string result = sourceString.Interpolate(x => abc, x => dateTime, x => now);
Starting from the accepted answer I created a generic extension method:
public static string Replace<T>(this string template, T value)
{
return Regex.Replace(template, #"{(?<exp>[^}]+)}", match => {
var p = Expression.Parameter(typeof(T), typeof(T).Name);
var e = System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(new[] { p }, null, match.Groups["exp"].Value);
return (e.Compile().DynamicInvoke(value) ?? "").ToString();
});
}
Answer from #ThePerplexedOne is better, but if you really need to avoid string interpolation, so
static string ReplaceMacro(string value, Job job)
{
return value?.Replace("{job.Name}", job.Name); //Output should be "Todo job for admin"
}
You should change your function to:
static string ReplaceMacro(Job obj, Func<dynamic, string> function)
{
return function(obj);
}
And call it:
Console.WriteLine(
ReplaceMacro(
new Job { Id = 1, Name = "Todo", Description = "Nothing" },
x => $"{x.Name} job for admin"));
If you really need this, you can do it using Roslyn, create string – class implementation like
var stringToInterpolate = "$#\"{{job.Name}} job for admin\"";
var sourceCode = $#"
using System;
class RuntimeInterpolation(Job job)
{{
public static string Interpolate() =>
{stringToInterpolate};
}}";
then make an assembly
var assembly = CompileSourceRoslyn(sourceCode);
var type = assembly.GetType("RuntimeInterpolation");
var instance = Activator.CreateInstance(type);
var result = (string) type.InvokeMember("Interpolate",
BindingFlags.Default | BindingFlags.InvokeMethod, null, instance, new object[] {new Job { Id = 1, Name = "Todo", Description="Nothing" }});
Console.WriteLine(result);
you'll get this code by runtime and you'll get your result (also you'll need to attach link to your job class to that assembly)
using System;
class RuntimeInterpolation(Job job)
{
public static string Interpolate() =>
$#"{job.Name} job for admin";
}
You can read about how to implement CompileSourceRoslyn here Roslyn - compiling simple class: "The type or namespace name 'string' could not be found..."
Wondering no one has mentioned mustache-sharp. Downloadable via Nuget.
string templateFromSomewhere = "url: {{Url}}, Name:{{Name}}";
FormatCompiler compiler = new FormatCompiler();
Generator generator = compiler.Compile(templateFromSomewhere);
string result = generator.Render(new
{
Url="https://google.com",
Name = "Bob",
});//"url: https://google.com, Name:Bob"
More examples could be found here, at the unit testing file.
The implementation I'd come up with very similar to giganoide's allowing callers to substitute the name used in the template for the data to interpolate from. This can accommodate things like feeding it anonymous types. It will used the provided interpolateDataAs name if provided, otherwise if it isn't an anonymous type it will default to the type name, otherwise it expects "data". (or specifically the name of the property) It's written as an injectable dependency but should still work as an extension method.
public interface ITemplateInterpolator
{
/// <summary>
/// Attempt to interpolate the provided template string using
/// the data provided.
/// </summary>
/// <remarks>
/// Templates may want to use a meaninful interpolation name
/// like "enquiry.FieldName" or "employee.FieldName" rather than
/// "data.FieldName". Use the interpolateDataAs to pass "enquiry"
/// for example to substitute the default "data" prefix.
/// </remarks>
string? Interpolate<TData>(string template, TData data, string? interpolateDataAs = null) where TData : class;
}
public class TemplateInterpolator : ITemplateInterpolator
{
/// <summary>
/// <see cref="ITemplateInterpolator.Interpolate(string, dynamic, string)"/>
/// </summary>
string? ITemplateInterpolator.Interpolate<TData>(string template, TData data, string? interpolateDataAs)
{
if (string.IsNullOrEmpty(template))
return template;
if (string.IsNullOrEmpty(interpolateDataAs))
{
interpolateDataAs = !typeof(TData).IsAnonymousType() ? typeof(TData).Name : nameof(data);
}
var parsed = Regex.Replace(template, #"{(?<exp>[^}]+)}", match =>
{
var param = Expression.Parameter(typeof(TData), interpolateDataAs);
var e = System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(new[] { param }, null, match.Groups["exp"].Value);
return (e.Compile().DynamicInvoke(data) ?? string.Empty).ToString();
});
return parsed;
}
For detecting the anonymous type:
public static bool IsAnonymousType(this Type type)
{
if (type.IsGenericType)
{
var definition = type.GetGenericTypeDefinition();
if (definition.IsClass && definition.IsSealed && definition.Attributes.HasFlag(TypeAttributes.NotPublic))
{
var attributes = definition.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false);
return (attributes != null && attributes.Length > 0);
}
}
return false;
}
Test Suite:
[TestFixture]
public class WhenInterpolatingATemplateString
{
[TestCase("")]
[TestCase(null)]
public void ThenEmptyValueReturedWhenNoTemplateProvided(string? template)
{
ITemplateInterpolator testInterpolator = new TemplateInterpolator();
var testData = new TestData { Id = 14, Name = "Test" };
var result = testInterpolator.Interpolate(template!, testData);
Assert.That(result, Is.EqualTo(template));
}
[Test]
public void ThenTheTypeNameIsUsedForTheDataReferenceForDefinedClasses()
{
ITemplateInterpolator testInterpolator = new TemplateInterpolator();
var testData = new TestData { Id = 14, Name = "Test" };
string template = "This is a record named \"{TestData.Name}\" with an Id of {testdata.Id}."; // case insensitive.
string expected = "This is a record named \"Test\" with an Id of 14.";
var result = testInterpolator.Interpolate(template, testData);
Assert.That(result, Is.EqualTo(expected));
}
[Test]
public void ThenTheDefaultNameIsUsedForTheDataReferenceForAnonymous()
{
ITemplateInterpolator testInterpolator = new TemplateInterpolator();
var testData = new { Id = 14, Name = "Test" };
string template = "This is a record named \"{data.Name}\" with an Id of {data.Id}.";
string expected = "This is a record named \"Test\" with an Id of 14.";
var result = testInterpolator.Interpolate(template, testData);
Assert.That(result, Is.EqualTo(expected));
}
[Test]
public void ThenTheProvidedDataReferenceNameOverridesTheTypeName()
{
ITemplateInterpolator testInterpolator = new TemplateInterpolator();
var testData = new TestData { Id = 14, Name = "Test" };
string template = "This is a record named \"{otherData.Name}\" with an Id of {otherData.Id}.";
string expected = "This is a record named \"Test\" with an Id of 14.";
var result = testInterpolator.Interpolate(template, testData, "otherData");
Assert.That(result, Is.EqualTo(expected));
}
[Test]
public void ThenExceptionIsThrownWhenTemplateReferencesUnknownDataValues()
{
ITemplateInterpolator testInterpolator = new TemplateInterpolator();
var testData = new TestData { Id = 14, Name = "Test" };
string template = "This is a record named \"{testData.Name}\" with an Id of {testData.Id}. {testData.ExtraDetails}";
Assert.Throws<ParseException>(() => { var result = testInterpolator.Interpolate(template, testData, "testData"); });
}
[Test]
public void ThenDataFormattingExpressionsAreApplied()
{
ITemplateInterpolator testInterpolator = new TemplateInterpolator();
var testData = new { Id = 14, Name = "Test", IsActive = true, EffectiveDate = DateTime.Today };
string template = "The active state is {data.IsActive?\"Yes\":\"No\"}, Effective {data.EffectiveDate.ToString(\"yyyy-MM-dd\")}";
string expected = "The active state is Yes, Effective " + DateTime.Today.ToString("yyyy-MM-dd");
var result = testInterpolator.Interpolate(template, testData);
Assert.That(result, Is.EqualTo(expected));
}
private class TestData
{
public int Id { get; set; }
public string Name { get; set; }
}
}
I really don't understand the point of your ReplaceMacro method...
But here's how it should work:
class Program
{
static void Main(string[] args)
{
var job = new Job { Id = 1, Name = "Todo", Description = "Nothing" };
Console.WriteLine($"{job.Name} job for admin");
Console.ReadLine();
}
}
But if you really want the dynamic feel to it, your ReplaceMacro method should just take one parameter, which is the job:
static string ReplaceMacro(Job job)
{
return $"{job.Name} job for admin.";
}
And use it like:
var job = new Job { Id = 1, Name = "Todo", Description = "Nothing" };
Console.WriteLine(ReplaceMacro(job));
Or something to that effect.
Consider the enum below:
public enum TestType
{
Mil,
IEEE
}
How can I parse the folowing strings to the above enum?
Military 888d Test in case of TestType.Mil
Or
IEEE 1394 in case of TestType.IEEE
My idea was to check if the first letters of string matches 'Mil' or 'IEEE' then I would set it as the enum I want, but the problemis there are other cases that should not be parsed!
Already answred by me : How to set string in Enum C#?
Enum cannot be string but you can attach attribute and than you can read the value of enum as below....................
public enum TestType
{
[Description("Military 888d Test")]
Mil,
[Description("IEEE 1394")]
IEEE
}
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
here is good article if you want to go through it : Associating Strings with enums in C#
My understanding of your situation is that the string can come in any format. You could have strings like "Military 888d Test", "Mil 1234 Test", "Milit xyz SOmething"...
In such a scenario, a simple Enum.Parse is NOT going to help. You will need to decide for each value of the Enum, which combinations do you want to allow. Consider the code below...
public enum TestType
{
Unknown,
Mil,
IEEE
}
class TestEnumParseRule
{
public string[] AllowedPatterns { get; set; }
public TestType Result { get; set; }
}
private static TestType GetEnumType(string test, List<TestEnumParseRule> rules)
{
var result = TestType.Unknown;
var any = rules.FirstOrDefault((x => x.AllowedPatterns.Any(y => System.Text.RegularExpressions.Regex.IsMatch(test, y))));
if (any != null)
result = any.Result;
return result;
}
var objects = new List<TestEnumParseRule>
{
new TestEnumParseRule() {AllowedPatterns = new[] {"^Military \\d{3}\\w{1} [Test|Test2]+$"}, Result = TestType.Mil},
new TestEnumParseRule() {AllowedPatterns = new[] {"^IEEE \\d{3}\\w{1} [Test|Test2]+$"}, Result = TestType.IEEE}
};
var testString1 = "Military 888d Test";
var testString2 = "Miltiary 833d Spiral";
var result = GetEnumType(testString1, objects);
Console.WriteLine(result); // Mil
result = GetEnumType(testString2, objects);
Console.WriteLine(result); // Unknown
The important thing is populating that rules object with the relevant regular expressions or tests. How you get those values in to the array, really depends on you...
try this var result = Enum.Parse(type, value);
Please try this way
TestType testType;
Enum.TryParse<TestType>("IEEE", out testType);
and it you want to compare string then
bool result = testType.ToString() == "IEEE";
Simple method will do it for you:
public TestType GetTestType(string testTypeName)
{
switch(testTypeName)
{
case "Military 888d Test":
return TestType.Mil;
case "IEEE 1394":
return TestType.IEEE;
default:
throw new ArgumentException("testTypeName");
}
}
EDIT
use Enum.GetNames:
foreach (var value in Enum.GetNames(typeof(TestType)))
{
// compare strings here
if(yourString.Contains(value))
{
// what you want to do
...
}
}
If you using .NET4 or later you can use Enum.TryParse. and Enum.Parse is available for .NET2 and later.