我有几个get属性,我希望能够像一组函数一样循环。我希望能够做到这样的事情
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);
}
这段代码非常破碎,但我认为它传达了我希望能够做到的想法。有谁知道我怎么能做到这一点?
答案 0 :(得分:3)
您可以使用反射来访问类型中的属性:
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;
}
}
请注意,反射很慢,如果有更好的方法,则不应使用此方法。例如,当您知道只有6个属性时,请单独浏览它们。
答案 1 :(得分:0)
您可以尝试使用GetProperties
示例:
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());
}
进一步信息:
GetProperties with flags的示例非常好,如果您想要访问特定的属性子集(仅限公共场所),它对您有用
答案 2 :(得分:0)
如果您已经知道要循环的所有属性,那么您可以试试这个
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);
}
如果没有,你可以使用这样的东西:
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);
}
答案 3 :(得分:0)
代码离工作还不远。 myProperties
变量应该是一个数组,您需要创建从属性中读取的函数。 (属性getter实际上是作为一个函数实现的,但你不能将它作为函数调用或获取它的引用。)然后你通过调用它们来使用它们。
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;
}
}
答案 4 :(得分:0)
如果您需要在数组中使用属性,因为您需要(如我所做)设置和/或获取多个相关(和相同类型)属性,这是您可以执行的操作。我知道反射是“慢'”,但对于我的使用案例,由于反射,重复代码(因此错误机会)减少的好处远远超过任何“慢”(这是无关紧要的)。这不处理索引属性,但可以从中轻松创建一个版本。
` 公共类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
`
` 公共类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
`
答案 5 :(得分:0)
您可以使用数组缓冲区并从中获取所有支持。通过这种方式,您可以非常快速地获取和设置:
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]; }
现在可以使用buf
访问所有道具:
foreach (var item in buf) {
myList.Add(item);
}
或直接访问:
buf[1] = 10;
x = buf[1];