Getting attributes values in another class - c#

I'm working in a project to get some information about Issuers. In MainWindow activity I have this line of code:
builder.AddCustomAttributes(typeof(IssuerActivity), new DesignerAttribute(typeof(IssuerDesigner)));
So I have a IssuerDesigner that I put in a listbox all of the Issuers in his contructor method and I save in an Issuer [] all of these.
Now, when I execute this rehosted workflow, I need to send this Issuer[] to IssuerActivity to analized in a foreach task everyone of them...
The question is: ¿What have I to do to for IssuerActivity gets Issuer[] that It's assigned in IssuerDesigner?

Your question is hard to follow but I beleive this is what you are looking for. You will have to use Reflection on your object to be able to grab the Attribute Values. It should be something like this.
MemberInfo[] members = builder.GetType().GetProperties();
foreach (MemberInfo m in members)
{
if (m.MemberType == MemberTypes.Property)
{
PropertyInfo p = m as PropertyInfo;
object[] attribs = p.GetCustomAttributes(false);
foreach (object attr in attribs)
{
IssuerDesigner d = attr as IssuerDesigner;
if (d != null)
{
foreach(object obj in d.Issuer)
{
DoSomething(obj);
}
}
}
}
}

Related

"z" is a variable but used like type

I am trying to use generic list as cast of the object. i have seen related questions and tried but didn't get, what i expected.
In the below code i am setting the value to the main response.
Here is code:
Type type = Type.GetType("className, AssemblyName"); <br/>
var z = typeof(List<>).MakeGenericType(type);
foreach (var key in abc.Keys)
{
var value = abc[key];
foreach (var property in ((List<z>)output.Response)[0].GetType().GetProperties().Where(p => p.CanRead && p.GetMethod.IsPublic).)
{
if(property.Name == ((List<Document>)value)[0].GetType().Name)
{
PropertyInfo propertyInfo = ((List<Policy>)output.Response)[0].GetType().GetProperty(property.Name);
propertyInfo.SetValue(((List<Policy>)output.Response)[0], ((List<Document>)value));
}
}
}
while accessing z in list. i am unable to do that. I have stuck from past few hour.Please help me out.
Thanks in Advance!

Get a list via reflection

I have some class that contains a List with a type of PropertyInfo:
public List<PropertyInfo> Properties {get; set;}
And I have an instance of that class, but it is not known which class it is at the run-time. So with that instance, in my case it's called P, I need to loop through the upper-mentioned list. Now I can get the value of the property by using:
var PropList = P.GetType().GetProperty("Properties").GetValue(this, null)
But if I try to loop through it:
foreach (var thisProp in PropList) - I get an error.
So, is there any other way to do this?
Thanks
You have to cast:
var PropList = P
.GetType()
.GetProperty("Properties")
.GetValue(P, null) as IEnumerable<PropertyInfo>; // notice "as ..."
// Since PropList is IEnumerable<T> you can loop over it
foreach (var thisProp in PropList) {
...
}
since GetValue(...) alone returns object.
After reviewing your code it's clear that
var PropList = P.GetType().GetProperty("Properties").GetValue(this, null)
does not return an ienumerable due to which you are getting and error. One possible solution To fix this issue you need to cast it to Ienumerable.
var PropList = P
.GetType()
.GetProperty("Properties")
.GetValue(this, null) as IEnumerable<PropertyInfo>;

Foreach enum values without casting

I have to cast enum but I want this to be as generic as possbile. How can I replace the Cast<XX>() part with propertyType?
foreach (var prop in MainType.GetProperties().Where(x => x.PropertyType.IsEnum))
{
var x = new { name = prop.Name, values = new List<object>() };
foreach (var v in Enum.GetValues(prop.PropertyType).Cast<XX>())
x.values.Add(new { p = v.GetAttribute<DescriptionAttribute>().Description,
c = v.GetAttribute<DefaultValueAttribute>().Value });
o.Add(x);
}
public static TAttribute GetAttribute<TAttribute>(this Enum value) where TAttribute : Attribute
{
var type = value.GetType();
var name = Enum.GetName(type, value);
return type.GetField(name)
.GetCustomAttributes(false)
.OfType<TAttribute>()
.SingleOrDefault();
}
public enum JobApplicationState : short
{
[Description("Active")]
[DefaultValue(typeof(string), "bg-primary text-highlight")]
Active = 1,
[Description("Passive")]
[DefaultValue(typeof(string), "bg-grey text-highlight")]
Passive = 2,
[Description("Rejected")]
[DefaultValue(typeof(string), "bg-danger text-highlight")]
Rejected = 3,
[Description("Accepted")]
[DefaultValue(typeof(string), "bg-success text-highlight")]
Accepted = 4
}
THIS WORKED!
foreach (MemberInfo m in prop.PropertyType.GetFields())
{
if (m.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault() != null && m.GetCustomAttributes(typeof(DefaultValueAttribute), true).FirstOrDefault() != null)
{
x.values.Add(
new
{
p = ((DescriptionAttribute)m.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault()).Description,
c = ((DefaultValueAttribute)m.GetCustomAttributes(typeof(DefaultValueAttribute), true).FirstOrDefault()).Value
});
}
}
You should realize that an enum is nothing more than a named wrapper around an integral value. I've described some details on how enums work here: Cast int to enum in C# .
The question here is to get attributes values from an enum. As you might imagine, this question is about getting attributes from the type, not about getting attributes from the value (there's no such thing). Still, if you call a method like void Foo<T>(T myEnum), the type T will hold all the necessary info, even though 'in real life' the value of myEnum is passed around as an integral type.
From this you can also deduce that you're actually looking for the attributes of the MemberInfo's of T, since you're looking for the members of the type (e.g. the enum). Again, all the details are in my post on how enums work. Hence the answer:
foreach (MemberInfo m in prop.PropertyType.GetFields())
{
// use m.GetAttribute(...)
}
Why don´t you simply cast to Enum:
foreach (var v in Enum.GetValues(prop.PropertyType).Cast<Enum>())
Now you can call your extension-method on every element within the returned list.
v.GetAttribute<MyType>()

What does SONAR Error AvoidRepetitiveCallsToPropertiesRule mean?

I have this below piece of code, which i always highlighted by SONAR as a MAJOR issue, because of violation of a rule called with the below message.
Multiple (3) calls to virtual property 'System.String System.Reflection.MemberInfo::get_Name()'.
And the rule description says
AvoidRepetitiveCallsToPropertiesRule
gendarme : AvoidRepetitiveCallsToPropertiesRule
The rule warn if virtual, or unlikely to be inline-able, property getters are called several times by a method. In most cases repetitive calls simply requires more time without any gains since the result will always be identical. You should ignore the reported defects if a different value is expected each time the property is called (e.g. calling DateTime.Now).**
private static void OverrideConfigurationValues(ConfigA configa,
ConfigB configb, ConfigC configc)
{
Type t = configa();
var properties = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
var overriddenvalues = new Dictionary<string, object>();
foreach (var prop in properties)
{
var value = prop.GetValue(configa,null);
if (value != null)
{
overriddenvalues.Add(prop.Name, value);
}
}
Type b = configb.GetType();
foreach (var prop in b.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!overriddenvalues.ContainsKey(prop.Name))
{
var value = prop.GetValue(b,null);
if (value != null)
{
overriddenvalues.Add(prop.Name, value);
}
}
}
foreach (var overriddenvalue in overriddenvalues)
{
var overriden = overriddenvalue;
foreach (var prop in configa.GetType().GetProperties().Where(prop => prop.Name == overriden.Key))
{
prop.SetValue(configa, overriddenvalue.Value,null);
}
}
}
If the SONAR is complaining about the line prop.Name which i have inside the foreach loop? How can i avoid it?
Ron Beyer's comments are proper answers to this question.
So, your code would look like this based on his comments:
...
foreach (var prop in b.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
var propName = prop.Name;
if (!overriddenvalues.ContainsKey(propName))
{
var value = prop.GetValue(b,null);
if (value != null)
{
overriddenvalues.Add(propName, value);
}
}
}
...
Note that the support of Gendarme rules was dropped in the 3.0 version of the C# plugin.

Is it possible to loop through a C# Class object?

I have a C# class that I want to loop through the properties as a key/value pair but don't know how.
Here is what I would like to do:
Foreach (classobjectproperty prop in classobjectname)
{
if (prop.name == "somename")
//do something cool with prop.value
}
Yup:
Type type = typeof(Form); // Or use Type.GetType, etc
foreach (PropertyInfo property in type.GetProperties())
{
// Do stuff with property
}
This won't give them as key/value pairs, but you can get all kinds of information from a PropertyInfo.
Note that this will only give public properties. For non-public ones, you'd want to use the overload which takes a BindingFlags. If you really want just name/value pairs for instance properties of a particular instance, you could do something like:
var query = foo.GetType()
.GetProperties(BindingFlags.Public |
BindingFlags.Instance)
// Ignore indexers for simplicity
.Where(prop => !prop.GetIndexParameters().Any())
.Select(prop => new { Name = prop.Name,
Value = prop.GetValue(foo, null) });
foreach (var pair in query)
{
Console.WriteLine("{0} = {1}", pair.Name, pair.Value);
}
Check out the solutions here - although that restricts to public properies the approach should work for you to get them all.

Categories