Reputation: 117
I have several get properties that I would like to be able to loop through like an array of functions. I would like to be able to do something like this
public int prop1 { get; }
public string prop2 { get; }
public int[] prop3 { get; }
public int prop4 { get; }
public string prop5 { get; }
public string prop6 { get; }
Func<var> myProperties = { prop1, prop2, prop3, prop4, prop5, prop6 };
ArrayList myList = new ArrayList();
foreach( var p in myProperties)
{
myList.Add(p);
}
This code is very broken, but I think it conveys the idea of what I would like to be able to do. Anyone know how I can achieve this?
Upvotes: 4
Views: 25908
Reputation: 1921
You can use an array buffer and get all prop from it. in this way you can get and set very fast:
public object[] buf = new object[5];
public int prop1 { get => buf[0]; }
public string prop2 { get => buf[1]; }
public int[] prop3 { get => buf[2]; }
public int prop4 { get => buf[3]; }
public string prop5 { get => buf[4]; }
public string prop6 { get => buf[5]; }
Now can access all prop with buf
:
foreach (var item in buf) {
myList.Add(item);
}
Or direct access :
buf[1] = 10;
x = buf[1];
Upvotes: 0
Reputation: 888
If you're needing your Properties in an Array, because you're needing to (as I did) Set and/or Get several related (and same-Typed) Properties, here's what you can do. I know Reflection is "'slow'", but for my use cases, the duplicate code (and therefore error chance) reduction benefits far outweigh any "'slowness'" (which are insignificant) due to Reflection. This does not handle Indexed Properties, but a version to so can easily be created from this.
` public class MyClass {
private string[] myBoolPropertyNames =
{
nameof(MyBool1Property),
nameof(MyBool2Property)
}; // MyBoolPropertyNames =
private MyClass()
{
foreach (var propertyName in myBoolPropertyNames)
{
ReflectionHelper.SetPropertyValue
(
parentObject: this,
propertyName: propertyName,
untypedPropertyValue: true
); // SetPropertyValue
} // foreach (var propertyName in myBoolPropertyNames)
foreach (var propertyName in myBoolPropertyNames)
{
bool boolPropertyValue = ReflectionHelper.GetPropertyValue<bool>
(
parentObject: this,
propertyName: propertyName
); // SetPropertyValue
Console.WriteLine($"Property '{propertyName}' value: {boolPropertyValue}");
} // foreach (var propertyName in myBoolPropertyNames)
}
public bool MyBool1Property { get; set; }
public bool MyBool2Property { get; set; }
} // MyClass
`
` public class ReflectionHelper {
public static PropertyType GetPropertyValue<PropertyType>
(
object parentObject,
string propertyName
)
{
if (parentObject == null)
{
throw new ArgumentException
(
$"Missing '{nameof(parentObject)}'."
);
} // if (parentObject == null)
PropertyInfo propertyInfo = parentObject.GetType().GetProperty(propertyName);
if (propertyInfo == null)
{
throw new ArgumentException
(
"No PropertyInfo found for Property: " + propertyName
);
} // if (propertyInfo == null)
object untypedPropertyValue = propertyInfo.GetValue(obj: parentObject);
Type propertyType =
(
Nullable.GetUnderlyingType(propertyInfo.PropertyType)
?? propertyInfo.PropertyType
); // propertyType =
object typedPropertyValue =
(
(untypedPropertyValue == null)
? null
: Convert.ChangeType(untypedPropertyValue, propertyType)
); // typedPropertyValue =
return (PropertyType)typedPropertyValue;
} // GetPropertyValue
public static void SetPropertyValue
(
object parentObject,
string propertyName,
object untypedPropertyValue
)
{
if (parentObject == null)
{
throw new ArgumentException
(
$"Missing '{nameof(parentObject)}'."
);
} // if (parentObject == null)
PropertyInfo propertyInfo = parentObject.GetType().GetProperty(propertyName);
if (propertyInfo == null)
{
throw new ArgumentException
(
"No PropertyInfo found for Property: " + propertyName
);
} // if (propertyInfo == null)
Type propertyType =
(
Nullable.GetUnderlyingType(propertyInfo.PropertyType)
?? propertyInfo.PropertyType
); // propertyType =
object typedPropertyValue =
(
(untypedPropertyValue == null)
? null
: Convert.ChangeType(untypedPropertyValue, propertyType)
); // typedPropertyValue =
propertyInfo.SetValue
(
obj: parentObject,
value: typedPropertyValue
); // propertyInfo.SetValue
} // SetPropertyValue
} // ReflectionHelper
`
Upvotes: 0
Reputation: 148980
If you know all the properties you want to loop through already, then you can try this
List<Reflection.PropertyInfo> myProperties = new List()<object>
{
typeof(SomeType).GetProperty("prop1"),
typeof(SomeType).GetProperty("prop2"),
typeof(SomeType).GetProperty("prop3"),
typeof(SomeType).GetProperty("prop4"),
typeof(SomeType).GetProperty("prop5"),
typeof(SomeType).GetProperty("prop6")
};
foreach(var p in myProperties)
{
var value = p.GetValue(someObject, new object[0]);
myList.Add(p);
}
If not, you can use something like this:
var myProperties =
from pi in someObject.GetType().GetProperties()
select new
{
pi.Name,
Value = pi.GetValue(object, new object[0])
};
foreach(var p in myProperties)
{
myList.Add(p.Value);
}
Upvotes: 1
Reputation: 700152
The code is not so far from working. The myProperties
variable should be an array, and you need to create functions that read from the properties. (The property getter is actually implemented as a function, but you can't call it as a function or get a reference to it.) Then you use them by calling them.
public class MyClass {
public int prop1 { get; set; }
public string prop2 { get; set; }
public int[] prop3 { get; set; }
public int prop4 { get; set; }
public string prop5 { get; set; }
public string prop6 { get; set; }
public ArrayList GetProperties() {
Func<object>[] myProperties = {
() => prop1, () => prop2, () => prop3,
() => prop4, () => prop5, () => prop6
};
ArrayList myList = new ArrayList();
foreach (var p in myProperties) {
myList.Add(p());
}
return myList;
}
}
Upvotes: 0
Reputation: 387507
You could use reflection to access the properties within your type:
class MyType
{
public int prop1 { get; }
public string prop2 { get; }
public int[] prop3 { get; }
public int prop4 { get; }
public string prop5 { get; }
public string prop6 { get; }
public List<string> GetAllPropertyValues()
{
List<string> values = new List<string>();
foreach (var pi in typeof(MyType).GetProperties())
{
values.Add(pi.GetValue(this, null).ToString());
}
return values;
}
}
Note that reflection is slow and you shouldn’t use this if there is a better way. For example when you know that there are only 6 properties, just go through them individually.
Upvotes: 7
Reputation: 5565
You can try to use GetProperties
Example:
PropertyInfo[] myPropertyInfo;
// Get the properties of 'Type' class object.
myPropertyInfo = Type.GetType("System.Type").GetProperties();
Console.WriteLine("Properties of System.Type are:");
for (int i = 0; i < myPropertyInfo.Length; i++)
{
Console.WriteLine(myPropertyInfo[i].ToString());
}
Further Info:
The example for GetProperties with flags is really nice, and it can be useful for you if you want to access to a specific subset of Properties (Like only the Public Ones)
Upvotes: 0