Consider the following class -
public class User
{
[Selected]
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
[Selected]
public int Code { get; set; }
public object GetValue()
{
// need to do something here
}
}
[Selected] here is nothing but a marker attribute. I want GetValue method to return an object which will have the [Selected]-marked properties with corresponding values. That is, in the code below -
private static void Execute()
{
User user = new User
{
Name = "alice",
Email = "[email protected]",
Password = "123456",
Code = 1234
};
var value = user.GetValue();
}
value should be an object with two properties Name and Code which should have the values "alice" and 1234 respectively.
After some searching I tried ExpandoObject (which I never used before) -
public object GetValue()
{
var dictionary = this.GetType().GetProperties().Where(p => p.GetCustomAttribute(typeof(Selected), false) != null).ToDictionary(p => p.Name);
dynamic expando = new ExpandoObject();
foreach (var item in dictionary)
{
object value = item.Value.GetValue(this);
((IDictionary<string, object>)expando).Add(item.Key, value);
}
return expando;
}
But it didn't serve my purpose - the client/consumer of value object somehow couldn't read/access the property values.
Any suggestions?
Edit :
There might be a lot of classes like User and the GetValue method will be called from within a generic method. So, at runtime I have no way to know what type the object is and which properties are marked.
What you did works well, you just have to use the keyword dynamic when you call the method
GetValue.If you are using var,
valuewill be of the same type as the return type of your function (i.eobject) at compile time. Therefore, if you try to dovalue.Nameyour compiler won't allow it because the classObjectdoesn't have any attributeName.dynamic tells your program to do the type checking at runtime.