C# 如何使用反射获取对象的值列表';匹配特定类型的字段?
请注意,为了简洁和可读性,我使用了更简单的类型、字段和方法 我已经为一个类定义了一个布尔属性,C# 如何使用反射获取对象的值列表';匹配特定类型的字段?,c#,reflection,C#,Reflection,请注意,为了简洁和可读性,我使用了更简单的类型、字段和方法 我已经为一个类定义了一个布尔属性,personProperty,其中我希望getter,get{}调用一个私有方法,personMethod(int arg)对在Person中定义的每个整型字段值进行调用(在本例中,\u age,\u phoneNumber)。它应该忽略所有其他类型,如readingList 这样,如果我要向Person添加另一个整数字段(或修改或删除任何Person字段名),我就不必更新personProperty的
personProperty
,其中我希望getter,get{}
调用一个私有方法,personMethod(int arg)
对在Person
中定义的每个整型字段值进行调用(在本例中,\u age
,\u phoneNumber
)。它应该忽略所有其他类型,如readingList
这样,如果我要向Person
添加另一个整数字段(或修改或删除任何Person
字段名),我就不必更新personProperty
的定义,根据设计选择,该定义取决于Person
类的所有整数字段(也就是说,开发人员永远不会引入一个他不希望personMethod
运行的int
字段)
公共类人物
{
私人互联网;
公共国际电话号码;
//受保护的国际未来国际;
字典_readingList=新字典();
公共财产
{
得到
{
// ...
bool personPropertyReturnValue;
列表结果列表=新列表();
foreach(个人列表中的int personFieldValue)
{
bool结果=personMethod(personFieldValue);
结果列表。添加(结果);
}
//使用'resultList'执行初始化personPropertyReturnValue的操作;
返回personPropertyReturnValue;
}
}
私人bool personMethod(intarg)
{
bool returnValue=true;
//执行一些操作来初始化'returnValue'`
返回值;
}
}
我需要知道我应该用什么来代替
个人列表
,以便它返回一个iterable值,该值存储在\u age
、\u phoneNumber
(以及所有其他未来的int
,如\u futureInt
中定义的\u-futureInt
).我不认为使用反射比每次添加字段时都调整属性更好,但这就是问题所在:
public class Person
{
private int _age;
public int _phoneNumber;
// protected int _futureInt;
Dictionary<string, string> _readingList = new Dictionary<string, string>();
public Person(int age){
_age = age;
}
public bool personProperty
{
get
{
List<bool> resultList = new List<bool>();
var intFields = this.GetType().GetFields(BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public)
.Where(f => f.FieldType == typeof(int))
.Select(f => f.GetValue(this)).Cast<int>();
foreach (int personFieldValue in intFields)
{
bool result = personMethod(personFieldValue);
resultList.Add(result);
}
// Do stuff with `resultList` that'll initialize personPropertyReturnValue;
bool personPropertyReturnValue = resultList.All(b => b);
return personPropertyReturnValue;
}
}
private bool personMethod(int arg)
{
return (arg > 0);
}
}
希望您没有将实际电话号码存储为
int
。请注意,请尽量遵循标准,除非字段名称只是示例,否则您不应该真正使用int
作为电话号码。@Scottannen来回答您的问题-我正在使用的数据类型,对应于在本例中,int
在含义上类似,因此对其调用某些方法是有意义的。我可以在另一篇文章中讨论细节,但我认为讨论更适合。调用顺序并不重要,因为对每个int
操作的方法的结果不依赖于任何以前的结果。不,更改声明顺序不会导致错误(我已经测试过)@MTV我明白。在这种情况下,我觉得几乎有义务提及它。最大的挑战之一是编写代码,以便其他人能够轻松理解和维护。在这种情况下,如果字段仅仅因为存在而产生了一些影响,那将是非常令人困惑的。重要的是能够看到一些东西并知道它的作用,并且是否已使用它。如果我们看到未使用的字段,我们会将其删除。如果我们更改了不应更改的内容,编译器会告诉我们。但在这种情况下,这些都不会发生-代码将以难以理解的方式表现出不同的行为。@MTV您不需要对此进行尝试捕获。您可以通过检查Fi来筛选类型eldType
属性,就像我在下面所做的那样,或者通过对值调用OfType()来实现。我对LINQ不是很熟悉,因此您可以帮助我验证表达式。选择(f=>f.GetValue(this)).Cast()
只需获取所有过滤的FieldInfo
对象,并将其强制转换为int
?这与。Where
LINQ表达式是重要的表达式,似乎可以保证不会抛出InvalidCastException
。@MTV这是正确的。但它不会强制转换FieldInfo
对象;它强制转换由Select
和GetValue
返回的字段值。这些值属于Object
类型,但它们是“装箱的int
s”这就是为什么我们将它们强制转换为int
,而不必担心InvalidCastException
。或者,您可以去掉Where
并使用。选择(f=>f.GetValue(this))。of type();
直接获取int
值。我使用了第一种方法,因为它在字段类型上过滤,而不是在值上过滤,这允许您访问更多的值。
public class Person
{
private int _age;
public int _phoneNumber;
// protected int _futureInt;
Dictionary<string, string> _readingList = new Dictionary<string, string>();
public Person(int age){
_age = age;
}
public bool personProperty
{
get
{
List<bool> resultList = new List<bool>();
var intFields = this.GetType().GetFields(BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public)
.Where(f => f.FieldType == typeof(int))
.Select(f => f.GetValue(this)).Cast<int>();
foreach (int personFieldValue in intFields)
{
bool result = personMethod(personFieldValue);
resultList.Add(result);
}
// Do stuff with `resultList` that'll initialize personPropertyReturnValue;
bool personPropertyReturnValue = resultList.All(b => b);
return personPropertyReturnValue;
}
}
private bool personMethod(int arg)
{
return (arg > 0);
}
}
var person1 = new Person(0);
Console.WriteLine(person1.personProperty); // False
var person2 = new Person(1);
Console.WriteLine(person2.personProperty); // False
var person3 = new Person(1) { _phoneNumber = 1 };
Console.WriteLine(person3.personProperty); // True