Get the Enum<T> value Description - c#

I have my enumHelper class that contains these:
public static IList<T> GetValues()
{
IList<T> list = new List<T>();
foreach (object value in Enum.GetValues(typeof(T)))
{
list.Add((T)value);
}
return list;
}
and
public static string Description(Enum value)
{
Attribute DescAttribute = LMIGHelper.GetAttribute(value, typeof(DescriptionAttribute));
if (DescAttribute == null)
return value.ToString();
else
return ((DescriptionAttribute)DescAttribute).Description;
}
my enum is something like:
public enum OutputType
{
File,
[Description("Data Table")]
DataTable
}
So far so good. All the previous work fine.
Now I want to add a new helper to return BindingList>, so I can link any enum to any combo using
BindingList<KeyValuePair<OutputType, string>> list = Enum<OutputType>.GetBindableList();
cbo.datasource=list;
cbo.DisplayMember="Value";
cbo.ValueMember="Key";
For that I added:
public static BindingList<KeyValuePair<T, string>> GetBindingList()
{
BindingList<KeyValuePair<T, string>> list = new BindingList<KeyValuePair<T, string>>();
foreach (T value in Enum<T>.GetValues())
{
string Desc = Enum<T>.Description(value);
list.Add(new KeyValuePair<T, string>(value, Desc));
}
return list;
}
But "Enum.Description(value)" is not even compiling:
Argument '1': cannot convert from 'T' to 'System.Enum'
How can I do that? Is that even possible?
Thank you.

Take a look at this article. You can do this using the System.ComponentModel.DescriptionAttribute or creating your own attribute:
/// <summary>
/// Provides a description for an enumerated type.
/// </summary>
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field,
AllowMultiple = false)]
public sealed class EnumDescriptionAttribute : Attribute
{
private string description;
/// <summary>
/// Gets the description stored in this attribute.
/// </summary>
/// <value>The description stored in the attribute.</value>
public string Description
{
get
{
return this.description;
}
}
/// <summary>
/// Initializes a new instance of the
/// <see cref="EnumDescriptionAttribute"/> class.
/// </summary>
/// <param name="description">The description to store in this attribute.
/// </param>
public EnumDescriptionAttribute(string description)
: base()
{
this.description = description;
}
}
You then need to decorate the enum values with this new attribute:
public enum SimpleEnum
{
[EnumDescription("Today")]
Today,
[EnumDescription("Last 7 days")]
Last7,
[EnumDescription("Last 14 days")]
Last14,
[EnumDescription("Last 30 days")]
Last30,
[EnumDescription("All")]
All
}
All of the "magic" takes place in the following extension methods:
/// <summary>
/// Provides a static utility object of methods and properties to interact
/// with enumerated types.
/// </summary>
public static class EnumHelper
{
/// <summary>
/// Gets the <see cref="DescriptionAttribute" /> of an <see cref="Enum" />
/// type value.
/// </summary>
/// <param name="value">The <see cref="Enum" /> type value.</param>
/// <returns>A string containing the text of the
/// <see cref="DescriptionAttribute"/>.</returns>
public static string GetDescription(this Enum value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
string description = value.ToString();
FieldInfo fieldInfo = value.GetType().GetField(description);
EnumDescriptionAttribute[] attributes =
(EnumDescriptionAttribute[])
fieldInfo.GetCustomAttributes(typeof(EnumDescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
{
description = attributes[0].Description;
}
return description;
}
/// <summary>
/// Converts the <see cref="Enum" /> type to an <see cref="IList" />
/// compatible object.
/// </summary>
/// <param name="type">The <see cref="Enum"/> type.</param>
/// <returns>An <see cref="IList"/> containing the enumerated
/// type value and description.</returns>
public static IList ToList(this Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
ArrayList list = new ArrayList();
Array enumValues = Enum.GetValues(type);
foreach (Enum value in enumValues)
{
list.Add(new KeyValuePair<Enum, string>(value, GetDescription(value)));
}
return list;
}
}
Finally, you can then simply bind the combobox:
combo.DataSource = typeof(SimpleEnum).ToList();

You should change:
public static string Description(Enum value)
{
...
}
to
public static string Description(T value)
{
...
}
so it accepts a value of the enumeration. Now here is where it gets tricky: you have a value, but attributes decorate the field which holds the value.
You actually need to reflect over the enumeration's fields and check the value of each against the value you've been given (results should be cached for performance):
foreach(var field in typeof(T).GetFields())
{
T fieldValue;
try
{
fieldValue = (T) field.GetRawConstantValue();
}
catch(InvalidOperationException)
{
// For some reason, one of the fields returned is {Int32 value__},
// which throws an InvalidOperationException if you try and retrieve
// its constant value.
//
// I am unsure how to check for this state before
// attempting GetRawConstantValue().
continue;
}
if(fieldValue == value)
{
var attribute = LMIGHelper.GetAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
return attribute == null ? value.ToString() : attribute.Description;
}
}
Edit addressing the follow-up question
The FillComboFromEnum method is missing the type parameter for the enum. Try this:
public static void FillComboFromEnum<T>(ComboBox Cbo, BindingList<KeyValuePair<T, string>> List) where T : struct
Notice I constrained the type to be a struct. It's not a full enumeration constraint, but it's closer than nothing.

Enum doesn't have a Description() method. The best you could do is have your enum implement an interface that has the Description() method. If you do that, then you can have
public static BindingList<KeyValuePair<T extends _interface_, String>> getBindingList()
and then inside of that you can refer to
T foo = ...?
foo.Description(...);

Related

Generic string to enum extension method with default value [duplicate]

I got an Int16 value, from the database, and need to convert this to an enum type. This is unfortunately done in a layer of the code that knows very little about the objects except for what it can gather through reflection.
As such, it ends up calling Convert.ChangeType which fails with an invalid cast exception.
I found what I consider a smelly workaround, like this:
String name = Enum.GetName(destinationType, value);
Object enumValue = Enum.Parse(destinationType, name, false);
Is there a better way, so that I don't have to move through this String operation?
Here's a short, but complete, program that can be used if anyone need to experiment:
using System;
public class MyClass
{
public enum DummyEnum
{
Value0,
Value1
}
public static void Main()
{
Int16 value = 1;
Type destinationType = typeof(DummyEnum);
String name = Enum.GetName(destinationType, value);
Object enumValue = Enum.Parse(destinationType, name, false);
Console.WriteLine("" + value + " = " + enumValue);
}
}
Enum.ToObject(.... is what you're looking for!
C#
StringComparison enumValue = (StringComparison)Enum.ToObject(typeof(StringComparison), 5);
VB.NET
Dim enumValue As StringComparison = CType([Enum].ToObject(GetType(StringComparison), 5), StringComparison)
If you do a lot of Enum converting try using the following class it will save you alot of code.
public class Enum<EnumType> where EnumType : struct, IConvertible
{
/// <summary>
/// Retrieves an array of the values of the constants in a specified enumeration.
/// </summary>
/// <returns></returns>
/// <remarks></remarks>
public static EnumType[] GetValues()
{
return (EnumType[])Enum.GetValues(typeof(EnumType));
}
/// <summary>
/// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
/// <remarks></remarks>
public static EnumType Parse(string name)
{
return (EnumType)Enum.Parse(typeof(EnumType), name);
}
/// <summary>
/// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
/// </summary>
/// <param name="name"></param>
/// <param name="ignoreCase"></param>
/// <returns></returns>
/// <remarks></remarks>
public static EnumType Parse(string name, bool ignoreCase)
{
return (EnumType)Enum.Parse(typeof(EnumType), name, ignoreCase);
}
/// <summary>
/// Converts the specified object with an integer value to an enumeration member.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
/// <remarks></remarks>
public static EnumType ToObject(object value)
{
return (EnumType)Enum.ToObject(typeof(EnumType), value);
}
}
Now instead of writing (StringComparison)Enum.ToObject(typeof(StringComparison), 5); you can simply write Enum<StringComparison>.ToObject(5);.
Based on the #Peter's answer here is the method for Nullable<int> to Enum conversion:
public static class EnumUtils
{
public static bool TryParse<TEnum>(int? value, out TEnum result)
where TEnum: struct, IConvertible
{
if(!value.HasValue || !Enum.IsDefined(typeof(TEnum), value)){
result = default(TEnum);
return false;
}
result = (TEnum)Enum.ToObject(typeof(TEnum), value);
return true;
}
}
Using EnumUtils.TryParse<YourEnumType>(someNumber, out result) becomes useful for many scenarios. For example, WebApi Controller in Asp.NET does not have default protection against invalid Enum params. Asp.NET will just use default(YourEnumType) value, even if some passes null, -1000, 500000, "garbage string" or totally ignores the parameter. Moreover, ModelState will be valid in all these cases, so one of the solution is to use int? type with custom check
public class MyApiController: Controller
{
[HttpGet]
public IActionResult Get(int? myEnumParam){
MyEnumType myEnumParamParsed;
if(!EnumUtils.TryParse<MyEnumType>(myEnumParam, out myEnumParamParsed)){
return BadRequest($"Error: parameter '{nameof(myEnumParam)}' is not specified or incorrect");
}
return this.Get(washingServiceTypeParsed);
}
private IActionResult Get(MyEnumType myEnumParam){
// here we can guarantee that myEnumParam is valid
}
If you are storing an Enum in a DataTable but don't know which column is an enum and which is a string/int, you can access the value this way:
foreach (DataRow dataRow in myDataTable.Rows)
{
Trace.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
foreach (DataColumn dataCol in myDataTable.Columns)
{
object v = dataRow[dataCol];
Type t = dataCol.DataType;
bool e = false;
if (t.IsEnum) e = true;
Trace.WriteLine((dataCol.ColumnName + ":").PadRight(30) +
(e ? Enum.ToObject(t, v) : v));
}
}

How to quickly search for objects of certain class or child classes in C#

I want to make a collection of objects of various classes, and be able to quickly search for all instances that can be assigned to a specific class, without having to iterate the entire list. I can use a Dictionary<System.Type, List<object>>, however that won't find me all child classes/interfaces.
public class Parent {
}
public class Child : Parent {
}
public class Other {
}
public class ObjHolder {
Dictionary<System.Type, List<object>> objs = new Dictionary<System.Type, List<object>>();
public void AddObject(object obj) {
if (!objs.ContainsKey(obj.GetType()) {
objs[obj.GetType()] = new List<object>();
}
objs[obj.GetType()].Add(obj);
}
public List<object> GetObjectsOfType<T>() {
return objs.ContainsKey(typeof(T)) ? objs[typeof(T)] : new List<object>();
}
}
Now this will work great for the following:
ObjHolder o = new ObjHolder();
o.AddObject(new Parent());
o.AddObject(new Other());
o.GetObjectsOfType<Parent>(); // Returns only the Parent object
But this won't work in the following case:
ObjHolder o = new ObjHolder();
o.AddObject(new Child());
o.AddObject(new Other());
o.GetObjectsOfType<Parent>(); // Returns an empty list
I want to be able to grab all objects that can be assigned to Parent, and that includes the Child object, but the code won't return it.
Any ideas how to get this done in an efficient matter?
So what you want is something similar to dictionary. Let us try to implement it step by step. My code is heavily commented so I will let the code do the talking. Basically all you have to do is leave bread crumbs along the way when you add your object into your object holder.
public class InheritanceInfo
{
private class InheritanceChain
{
/// <summary>
/// LinkedList which holds inheritance chain from least derived to most derived for a given Type.
/// </summary>
private readonly LinkedList<Type> _linkedList = new LinkedList<Type>();
/// <summary>
/// Creates an Inheritance chain for a given type which holds information about base types.
/// </summary>
/// <param name="t">Type for which inheritance chain will be created.</param>
public InheritanceChain(Type t)
{
Type type = t;
do
{
if (type == typeof(object))
{
break;
}
_linkedList.AddFirst(type);
type = type.BaseType;
} while (true);
}
/// <summary>
/// First element of LinkedList. This will be used for iteration.
/// </summary>
public LinkedListNode<Type> First => _linkedList.First;
}
/// <summary>
/// Dictionary which holds Type vs DerivedTypes information. Basically does the all handling.
/// </summary>
private readonly ConcurrentDictionary<Type, SingleStepDerivedTypes> _inheritanceDictionary;
/// <summary>
/// InheritanceInfo class holds information about each Type's inheritance tree.
/// Each Type holds information about one step down the inheritance tree.
/// Example: public class C:B{}
/// public class B:A{}
/// public class A {}
/// Inheritance infor for class A holds info about only B because C is derived from B and
/// it is not a direct descendant of A.
/// </summary>
public InheritanceInfo() {
_inheritanceDictionary = new ConcurrentDictionary<Type, SingleStepDerivedTypes>();
}
/// <summary>
/// Updates the given Type inheritance tree info.
/// </summary>
/// <param name="type"></param>
public void Update(Type type) {
var element = new InheritanceChain(type).First;
while (element.Next != null) {
_inheritanceDictionary.AddOrUpdate(element.Value, (_)=>AddValueFactory(element.Next.Value), (_,sdt)=>UpdateValueFactory(element.Next.Value,sdt));
element = element.Next;
}
}
/// <summary>
/// Gets all the assignable types for the given type t.
/// </summary>
/// <param name="t">Type for which assignable types will be searched.</param>
/// <returns>All the assignable types for Type t.</returns>
public IEnumerable<Type> GetAssignables(Type t)
{
if(_inheritanceDictionary.TryGetValue(t ,out var derivedTypes) == false) {
return Array.Empty<Type>();
}
var recursive = derivedTypes.GetTypes().SelectMany(tp=>GetAssignables(tp));
return recursive.Concat(derivedTypes.GetTypes());
}
/// <summary>
/// Add value to the dictionary
/// </summary>
/// <param name="t">Type to add to ConcurrentDictionary</param>
/// <returns>SingleStepDerivedTypes which holds information about derived type t</returns>
private static SingleStepDerivedTypes AddValueFactory(Type t) {
var s = new SingleStepDerivedTypes();
s.Add(t);
return s;
}
/// <summary>
/// Updates the already created SingleStepDerivedTypes object.
/// </summary>
/// <param name="t">Type to add</param>
/// <param name="sdt">SingleStepDerivedTypes</param>
/// <returns>Updated SingleStepDerivedTypes.</returns>
private static SingleStepDerivedTypes UpdateValueFactory(Type t, SingleStepDerivedTypes sdt) {
sdt.Add(t);
return sdt;
}
}
public class SingleStepDerivedTypes
{
/// <summary>
/// HashSet which holds information about derived Types.
/// </summary>
private readonly HashSet<Type> _singleStepDerivedTypes;
/// <summary>
/// Constructor ;)
/// </summary>
public SingleStepDerivedTypes() {
_singleStepDerivedTypes = new HashSet<Type>();
}
/// <summary>
/// Adds a Type to the Derived Type information.
/// </summary>
/// <param name="type">Type to add.</param>
public void Add(Type type) {
_singleStepDerivedTypes.Add(type);
}
/// <summary>
/// Gets the contained information about types.
/// </summary>
/// <returns>IEnumerable of Types contained in this object.</returns>
public IEnumerable<Type> GetTypes() {
return _singleStepDerivedTypes;
}
}
Finally let us have a look at ObjectHolder as I imagined it to be. The hard part in your case, I think you did not keep the Single Responsibility principle and tried to do everything in one go.
public class Objectholder
{
/// <summary>
/// Holds Type vs object information.
/// Each object is seperated into its own Type.
/// </summary>
private readonly ConcurrentDictionary<Type, List<object>> _dict = new ConcurrentDictionary<Type, List<object>>();
/// <summary>
/// I already explained about this class before so here I will pass.
/// </summary>
private readonly InheritanceInfo inheritanceInfo = new InheritanceInfo();
/// <summary>
/// Adds an object to ObjectHolder.
/// </summary>
/// <param name="obj">Object to add</param>
public void AddObject(object obj) {
_dict.AddOrUpdate(obj.GetType(), t => AddValueFactory(obj), (t, li) => UpdateValueFactory(obj, li));
}
/// <summary>
/// Gets Objects which are assignable to type of T.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public IEnumerable<T> GetObjectsOf<T>() {
var tree = inheritanceInfo.GetAssignables(typeof(T)).Concat(new[] { typeof(T) });
return tree.SelectMany(t => _dict[t]).Cast<T>();
}
/// <summary>
/// Adds a value to dictionary.
/// </summary>
/// <param name="obj">Object to add.</param>
/// <returns></returns>
private List<object> AddValueFactory(object obj)
{
inheritanceInfo.Update(obj.GetType());
var l = new List<object>();
l.Add(obj);
return l;
}
/// <summary>
/// Updates a value in dictionary.
/// </summary>
/// <param name="obj">Object to add.</param>
/// <param name="li">List of objects</param>
/// <returns></returns>
private List<object> UpdateValueFactory(object obj, List<object> li)
{
inheritanceInfo.Update(obj.GetType());
li.Add(obj);
return li;
}
}
// Mock classes
public class A { }
public class B : A { }
public class C : B { }
The usage of ObjectHolder is the same as the way you wanted to do.
var a = new A();
var b = new B();
var c = new C();
var objectholder = new Objectholder();
objectholder.AddObject(a);
objectholder.AddObject(b);
objectholder.AddObject(c);
// Contains A and B and C
var allA = objectholder.GetObjectsOf<A>().ToArray();
You can use the Type.IsAssignableFrom method to determine which classes are assignable to the generic.
Change the GetObjectsOfType<T> method to the following:
return objs.Where(x => typeof(T).IsAssignableFrom(x.Key))
.Select(x => x.Value)
.ToList<object>();
And also:
objs[obj.GetType()] = obj;
should be:
objs[obj.GetType()].Add(obj);
If I understand it correctly, if B inherits A and you search for A, you want to return all B objects as well.
I would do it this way: Change your existing AddObject method to add the object to multiple collections. You can use Type.BaseType property to get the base type. Do it in a loop, until you reach object class.
public void AddObject(object obj) {
Type type;
do {
type = obj.GetType();
if (!objs.ContainsKey(type) {
objs[type] = new List<object>();
}
objs[type] = obj;
if(type == typeof(object)) break;
type = type.BaseType;
} while(true);
}
You need to check that if cached list contains an Assignable object from type T. Try code below that check for this relation
public List<object> GetObjectsOfType<T>()
{
foreach (var pair in objs)
{
if (pair.Key == typeof(T) || typeof(T).IsAssignableFrom(pair.Key))
{
return pair.Value;
}
}
return new List<object>();
}
I know that your code above is just to demonstrate the case, but there is a bug in AddObject function, you always save an object rather than a list, the function should be something like this:
public void AddObject(object obj)
{
if (!objs.ContainsKey(obj.GetType()))
{
objs[obj.GetType()] = new List<object>() { obj };
}
else
{
objs[obj.GetType()].Add(obj);
}
}

c# creating a dynamically anonymous types (var) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I need to create a anonymous type (HAS to be a var). Like this:
var sizes = new {
size = new { Medium = "1", Large = "-3", XL = "10%" }
};
It has to be dynamically so the next time this could also happen:
var sizes = new {
size = new { 3XL = "5", 4XL = "5%", 5XL = "-10%" }
};
How do I do this in C# winforms?
How do i fill in the var sizes? It has to be in this order!
You can create a dynamic type at runtime which contains methods and properties of any type using System.Reflection.Emit, you can assign default values into your properties within the dynamic type created. This is not a trivial exercise and it needs some work, but when you have the base code complete using it in your code is easy.
First you need to attach your dynamic type to your current AppDomain.
private AssemblyName _assemblyName;
private AssemblyBuilder _asssemblyBuilder;
private ModuleBuilder _moduleBuilder;
private Dictionary<SignatureBuilder, Type> _classes;
private ReaderWriterLock _rwLock;
private TypeBuilder _typeBuilder;
private string _typeName;
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="moduleName">The name of the assembly module.</param>
public DynamicTypeBuilder(string moduleName)
{
// Make sure the page reference exists.
if (moduleName == null) throw new ArgumentNullException("moduleName");
// Create the nw assembly
_assemblyName = new AssemblyName(moduleName);
_asssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.Run);
// Create only one module, therefor the
// modile name is the assembly name.
_moduleBuilder = _asssemblyBuilder.DefineDynamicModule(_assemblyName.Name);
// Get the class unique signature.
_classes = new Dictionary<SignatureBuilder, Type>();
_rwLock = new ReaderWriterLock();
}
The dynamic property class can be
/// <summary>
/// Dynamic property builder, with value assigned.
/// </summary>
public class DynamicPropertyValue
{
object value;
string name;
Type type;
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="name">The name of the property.</param>
/// <param name="type">The type of the property</param>
/// <param name="value">The value of the property.</param>
public DynamicPropertyValue(string name, Type type, object value)
{
if (name == null) throw new ArgumentNullException("name");
if (type == null) throw new ArgumentNullException("type");
if (value == null) throw new ArgumentNullException("value");
this.name = name;
this.type = type;
this.value = value;
}
/// <summary>
/// Gets, the property name.
/// </summary>
public string Name
{
get { return name; }
}
/// <summary>
/// Gets, the property type.
/// </summary>
public Type Type
{
get { return type; }
}
/// <summary>
/// Gets, the property value.
/// </summary>
public object Value
{
get { return value; }
}
}
The dynamic method class can be
/// <summary>
/// Dynamic method builder.
/// </summary>
public class DynamicMethod
{
string name;
IEnumerable<Type> parameters;
Type returnType;
Action<TypeBuilder> buildAction = null;
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="name">The name of the method.</param>
/// <param name="parameters">The collection parameter types.</param>
/// <param name="returnType">The return type.</param>
public DynamicMethod(string name, IEnumerable<Type> parameters, Type returnType)
{
if (name == null) throw new ArgumentNullException("name");
this.name = name;
this.parameters = parameters;
this.returnType = returnType;
}
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="name">The name of the method.</param>
/// <param name="parameters">The collection parameter types.</param>
/// <param name="returnType">The return type.</param>
/// <param name="buildAction">The build action.</param>
public DynamicMethod(string name, IEnumerable<Type> parameters, Type returnType, Action<TypeBuilder> buildAction)
{
if (name == null) throw new ArgumentNullException("name");
this.name = name;
this.parameters = parameters;
this.returnType = returnType;
this.buildAction = buildAction;
}
/// <summary>
/// Gets, the method name.
/// </summary>
public string Name
{
get { return name; }
}
/// <summary>
/// Gets, the collection of parameters
/// </summary>
public IEnumerable<Type> Parameters
{
get { return parameters; }
}
/// <summary>
/// Gets, the return type.
/// </summary>
public Type ReturnType
{
get { return returnType; }
}
/// <summary>
/// Gets, build action.
/// </summary>
public Action<TypeBuilder> BuildAction
{
get { return buildAction; }
}
}
Start the create process.
/// <summary>
/// Create a new instance of the dynamic type.
/// </summary>
/// <param name="typeName">The name of the type.</param>
/// <param name="properties">The collection of properties to create in the type.</param>
/// <param name="methods">The collection of methods to create in the type.</param>
/// <returns>The new instance of the type.</returns>
public object Create(string typeName, IEnumerable<DynamicPropertyValue> properties, IEnumerable<DynamicMethod> methods)
{
// Make sure the page reference exists.
if (typeName == null) throw new ArgumentNullException("typeName");
if (properties == null) throw new ArgumentNullException("properties");
if (methods == null) throw new ArgumentNullException("methods");
_typeName = typeName;
// Create the dynamic type collection
List<DynamicProperty> prop = new List<DynamicProperty>();
foreach (DynamicPropertyValue item in properties)
prop.Add(new DynamicProperty(item.Name, item.Type));
// Return the create type.
object instance = CreateEx(typeName, prop.ToArray(), methods);
PropertyInfo[] infos = instance.GetType().GetProperties();
// Assign each type value
foreach (PropertyInfo info in infos)
info.SetValue(instance, properties.First(u => u.Name == info.Name).Value, null);
// Return the instance with values assigned.
return instance;
}
If this is something you can use the complete source code for the dynamic type builder can be found at https://github.com/nequeo/misc/blob/master/csharp/DynamicTypeBuilder.cs

Name of class property to string

I have searched endlessly for a thread that specifies exactly my question but I cannot find it.
I want to take a class property and just take the property out of it as a string!
public class Foo
{
public Foo ()
{
}
public int MyProperty { get; set; }
}
Then I want to have the string "MyProperty" in the end, something like this:
Foo f = new Foo();
string s = Helperfunction(f.MyProperty);
string Helperfunction( X )
{
string MyString;
//do something with X
return MyString;
}
How difficult would this be to realize just with maybe a helperfunction?
So the output should be "MyProperty"
Because I dont want to hard code it, and as soon as I would ever refactor the property name, it would still work without editing the hardcoded string!
You can use reflection to get the name, here is a helper class I use:
public static class MemberName
{
/// <summary>
/// *** WARNING - Uses reflection - use responsibly ***
/// </summary>
/// <param name="instance"></param>
/// <param name="expression"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static string GetMemberName<T>(this T instance, Expression<Func<T, object>> expression)
{
return GetMemberName(expression);
}
/// <summary>
/// *** WARNING - Uses reflection - use responsibly ***
/// </summary>
/// <param name="expression"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static string GetMemberName<T>(Expression<Func<T, object>> expression)
{
if (expression == null)
{
throw new ArgumentException("The expression cannot be null.");
}
return GetMemberName(expression.Body);
}
/// <summary>
/// *** WARNING - Uses reflection - use responsibly ***
/// </summary>
/// <param name="instance"></param>
/// <param name="expression"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static string GetMemberName<T>(this T instance, Expression<Action<T>> expression)
{
return GetMemberName(expression);
}
/// <summary>
/// *** WARNING - Uses reflection - use responsibly ***
/// </summary>
/// <param name="expression"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static string GetMemberName<T>(Expression<Action<T>> expression)
{
if (expression == null)
{
throw new ArgumentException("The expression cannot be null.");
}
return GetMemberName(expression.Body);
}
private static string GetMemberName(Expression expression)
{
if (expression == null)
{
throw new ArgumentException("The expression cannot be null.");
}
if (expression is MemberExpression)
{
// Reference type property or field
var memberExpression = (MemberExpression)expression;
return memberExpression.Member.Name;
}
if (expression is MethodCallExpression)
{
// Reference type method
var methodCallExpression = (MethodCallExpression)expression;
return methodCallExpression.Method.Name;
}
if (expression is UnaryExpression)
{
// Property, field of method returning value type
var unaryExpression = (UnaryExpression)expression;
return GetMemberName(unaryExpression);
}
throw new ArgumentException("Invalid expression");
}
private static string GetMemberName(UnaryExpression unaryExpression)
{
if (unaryExpression.Operand is MethodCallExpression)
{
var methodExpression = (MethodCallExpression)unaryExpression.Operand;
return methodExpression.Method.Name;
}
return ((MemberExpression)unaryExpression.Operand).Member.Name;
}
}
And an example usage:
string propName = MemberName.GetMemberName<Foo>(x => x.MyProperty);
I don't quite understand the question, but if you want to do something with the propertyname, you could have a look at the CallerMemberName attribute.
string Helperfunction([CallerMemberName]string X = null )
{
return "PropertyName: " + X;
}
If you call this method within a property getter, then it will output the name of the property:
public class Foo
{
public string Foo { get { Trace.WriteLine (SomeFunction()); } }
}
Will output "MyProperty"

Using System.Reflection to retrieve a list of const string fields

I've created a class of classes (showing one of them) with const string that I want to itarate on.
public static class HTDB_Cols
{
public sealed class Assistant
{
public const string EntryID = "entryID",
CustName = "custName",
SerialNum = "serialNum",
UserName = "userName",
Password = "password",
EndDate = "end_date",
CustID = "custID",
TmpCheck = "tmpCheck",
Isfamily = "isfamily",
Isserver = "isserver";
}
}
public static class DB
{
public static void insert(string TableName)
{
ColumnsCollection = typeof(HTDB_Cols).GetNestedTypes().Where(f => f.DeclaringType.Name.ToLower().Equals(TableName.ToLower()));
}
}
The code above shows my attempt, but even after lots of trial and error I still couldn't get it right.
I want to have a list of all columns as const collection array or list.
var dict = typeof(HTDB_Cols).GetNestedTypes()
.First(t=>String.Compare(t.Name,TableName,true)==0)
.GetFields()
.ToDictionary(f => f.Name, f => f.GetValue(null));
To get a list
var list = typeof(HTDB_Cols).GetNestedTypes()
.First(t => String.Compare(t.Name, TableName, true) == 0)
.GetFields()
.Select(f => f.GetValue(null) as string)
.ToList();
It looks like what you need is an enum:
enum Assistant
{
EntryID,
CustName,
SerialNum,
UserName,
Password,
EndDate,
CustID,
TmpCheck,
Isfamily,
Isserver
};
You can then get all of those names as strings by doing:
string[] allNames = Enum.GetNames(typeof(Assistant));
As long as it's acceptable for you to have the names of the variables be the actual values that you care about, that's a valid option. I note that they're not quite the same in your example, but it's mostly just casing. If you can deal with using the variable names as the values, or changing the variable names to be the values you need, then that's likely to be your best option.
Now, if it really is important for the variable names to be different than the values they represent, or if you need to represent values that are illegal identifiers (for example, one of your values has a space, that's no good, and they couldn't ever start with a digit, or they might just be too long to be a convenient name). If that's the case, then what you really want is an enum that's backed by a string, rather than an integer or other numeric type. That's not strictly possible in C#, but since this has come up before I actually wrote the following class which is my best attempt at creating my own string backed enum. If you really need variable names that differ from the string values they represent, this should work for you.
All of the important stuff is right at the top, most everything after Equals is just syntactic sugar.
public struct StringEnum
{
#region Code that is to be configured
//For each value to be publicly exposed add a new field.
public static readonly StringEnum Alpha = new StringEnum("Alpha Value");
public static readonly StringEnum Beta = new StringEnum("Beta Value");
public static readonly StringEnum Invalid = new StringEnum("Invalid");
public static IEnumerable<StringEnum> AllValues
{
get
{
yield return Alpha;
yield return Beta;
yield return Invalid;
//...
//add a yield return for all instances here.
//TODO refactor to use reflection so it doesn't need to be manually updated.
}
}
#endregion
private string value;
/// <summary>
/// default constructor
/// </summary>
//private Group()
//{
// //You can make this default value whatever you want. null is another option I considered
// //(if this is a class an not a struct), but you
// //shouldn't have this be anything that doesn't exist as one of the options defined at the top of
// //the page.
// value = "Invalid";
//}
/// <summary>
/// primary constructor
/// </summary>
/// <param name="value">The string value that this is a wrapper for</param>
private StringEnum(string value)
{
this.value = value;
}
/// <summary>
/// Compares the StringEnum to another StringEnum, or to a string value.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
if (obj is StringEnum)
{
return this.Equals((StringEnum)obj);
}
string otherString = obj as string;
if (otherString != null)
{
return this.Equals(otherString);
}
throw new ArgumentException("obj is neither a StringEnum nor a String");
}
/// <summary>
/// Strongly typed equals method.
/// </summary>
/// <param name="other">Another StringEnum to compare this object to.</param>
/// <returns>True if the objects are equal.</returns>
public bool Equals(StringEnum other)
{
return value == other.value;
}
/// <summary>
/// Equals method typed to a string.
/// </summary>
/// <param name="other">A string to compare this object to.
/// There must be a Group associated with that string.</param>
/// <returns>True if 'other' represents the same Group as 'this'.</returns>
public bool Equals(string other)
{
return value == other;
}
/// <summary>
/// Overridden equals operator, for convenience.
/// </summary>
/// <param name="first"></param>
/// <param name="second"></param>
/// <returns>True if the objects are equal.</returns>
public static bool operator ==(StringEnum first, StringEnum second)
{
return object.Equals(first, second);
}
public static bool operator !=(StringEnum first, StringEnum second)
{
return !object.Equals(first, second);
}
/// <summary>
/// Properly overrides GetHashCode so that it returns the hash of the wrapped string.
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return value.GetHashCode();
}
/// <summary>
/// returns the internal string that this is a wrapper for.
/// </summary>
/// <param name="stringEnum"></param>
/// <returns></returns>
public static implicit operator string(StringEnum stringEnum)
{
return stringEnum.value;
}
/// <summary>
/// Parses a string and returns an instance that corresponds to it.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static StringEnum Parse(string input)
{
return AllValues.Where(item => item.value == input).FirstOrDefault();
}
/// <summary>
/// Syntatic sugar for the Parse method.
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
public static explicit operator StringEnum(string other)
{
return Parse(other);
}
/// <summary>
/// A string representation of this object.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return value;
}
}

Categories