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,
value
will be of the same type as the return type of your function (i.eobject
) at compile time. Therefore, if you try to dovalue.Name
your compiler won't allow it because the classObject
doesn't have any attributeName
.dynamic tells your program to do the type checking at runtime.