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

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.

Related

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>;

reflection to invoke methods of unknown property types

I want to call the generic method, 'get_', for each property, IEnumerable<class>, of my view model class to avoid creating lengthy switch statements that explicitly get each list... Does anyone know how to get the object type and method generically?
foreach (var prop in vm.GetType().GetProperties().Where(x => x.GetCustomAttributes<ExportAttribute>().Any()))
{
var objType = ??;
var method = objType.GetMethod(<by name>);
var list = method.Invoke(prop, null);
foreach (var item in list)
{
//do something
}
}
I would use something like:
foreach (var prop in vm.GetType()
.GetProperties()
.Where(x => x.GetCustomAttributes<ExportAttribute>().Any()))
{
var list = (IEnumerable) prop.GetValue(vm, null);
foreach (var item in list)
{
// do something
}
}
Now item will be typed as object... but you can't really do better than that anyway. Your "do something" code can't use any members of the element type anyway, because it could be any type.
If, on the other hand, you know that every property will be something implementing IEnumerable<T> where T will in each case have a common base type, then due to the generic covariance of IEnumerable<T> introduced in .NET 4, you can write:
foreach (var prop in vm.GetType()
.GetProperties()
.Where(x => x.GetCustomAttributes<ExportAttribute>().Any()))
{
var list = (IEnumerable<BaseType>) prop.GetValue(vm, null);
foreach (var item in list)
{
// do something
}
}
Then you can access item.PropertyDeclaredInBaseType.
Note that I've changed the target of the call to vm instead of null, as presumably you want those instance properties...

How can i get custom attribute prop's value?

I use MVC and c# .. how can i get property's value?
Thank you
foreach (var prop in this.GetType().GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(CalcProgressAttribute))))
{
//i need prop 's value here
}
Try this, to make GetProperty work as you expect:
foreach (var prop in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(prop => Attribute.IsDefined(prop, typeof(CalcProgressAttribute))))
{
object value = prop.GetValue(this, null);
}
I don't know wether your foreach loop works, because i can not proof the following part of your code:
.Where(prop => Attribute.IsDefined(prop, typeof(CalcProgressAttribute)))). But without the Where the loop will go through all properties.

How to access contents of Object If I don't know the structure in c#?

I have an object and I don't know its structure until runtime. So is there any way to access data from the object ?
Thanks.
PS: I can't think of any other details to provide, please ask me if this isn't enough!
Well, you can do with with reflection. For example:
public static void ShowProperties(object o)
{
if (o == null)
{
Console.WriteLine("Null: no properties");
return;
}
Type type = o.GetType();
var properties = type.GetProperties(BindingFlags.Public
| BindingFlags.Instance);
// Potentially put more filtering in here
foreach (var property in properties.Where
(p => p.CanRead && p.GetIndexParameters().Length == 0))
{
Console.WriteLine("{0}: {1}", property.Name, property.GetValue(o, null));
}
}
Look at the Type API for ways to get methods, events, fields, nested types etc.
Have a look at Reflection
You can use reflection to determine what properties, methods, and fields an object has. take a look at the methods on the Type type

C# - Reflection using Generics: Problem with Nested collections of ILists

I would like to be able to print object properties, and I've hit a snag when I hit nested collections of the iLists.
foreach (PropertyInformation p in properties)
{
//Ensure IList type, then perform recursive call
if (p.PropertyType.IsGenericType)
{
// recursive call to PrintListProperties<p.type?>((IList)p," ");
}
Can anyone please offer some help?
Cheers
KA
I'm just thinking aloud here. Maybe you can have a non generic PrintListProperties method that looks something like this:
private void PrintListProperties(IList list, Type type)
{
//reflect over type and use that when enumerating the list
}
Then, when you come across a nested list, do something like this:
if (p.PropertyType.IsGenericType)
{
PringListProperties((Ilist)p,p.PropertyType.GetGenericArguments()[0]);
}
Again, haven't tested this, but give it a whirl...
foreach (PropertyInfo p in props)
{
// We need to distinguish between indexed properties and parameterless properties
if (p.GetIndexParameters().Length == 0)
{
// This is the value of the property
Object v = p.GetValue(t, null);
// If it implements IList<> ...
if (v != null && v.GetType().GetInterface("IList`1") != null)
{
// ... then make the recursive call:
typeof(YourDeclaringClassHere).GetMethod("PrintListProperties").MakeGenericMethod(v.GetType().GetInterface("IList`1").GetGenericArguments()).Invoke(null, new object[] { v, indent + " " });
}
Console.WriteLine(indent + " {0} = {1}", p.Name, v);
}
else
{
Console.WriteLine(indent + " {0} = <indexed property>", p.Name);
}
}
p.PropertyType.GetGenericArguments()
will give you an array of the type arguments. (in ths case, with just one element, the T in IList<T>)
var dataType = myInstance.GetType();
var allProperties = dataType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
var listProperties =
allProperties.
Where(prop => prop.PropertyType.GetInterfaces().
Any(i => i == typeof(IList)));

Categories