如何遍历所有字符串属性并使用 System.Reflection 更改它们的值
How to iterate through all string properties and change their values using System.Reflection
我需要遍历一个项目的所有 String
属性,检索它们的值,并操纵这些值——不需要知道项目的名称或 属性 本身。到目前为止,我看到的所有 SetValue
示例都假设您知道 属性 的名称,并使用该名称来引用它。在我的例子中,我没有按名称调用任何东西,而是简单地遍历每个字符串。
public class SpecialClass
{
public string MyString1 { get; set; }
public string MyString2 { get; set; }
public void Sanitize()
{
Type CheckItemType = typeof(SpecialClass);
Type strType = typeof(System.String);
PropertyInfo[] propInfos = CheckItemType.GetProperties(
BindingFlags.Public | BindingFlags.Instance);
foreach (var propInfo in propInfos)
{
if (null != propInfo && propInfo.CanWrite)
{
if (propInfo.PropertyType == typeof(System.String))
{
// Retrieve the value of the string, manipulate, and then set it
}
}
}
}
}
在上面的代码中,Sanitize
方法将循环遍历 class 中的字符串,并在满足特定条件时调整它们的值。
虽然我找到了 this post,但它描述的内容似乎要求您知道项目的名称和 属性。就我而言,我也不知道。我有一个方法,其目的是对 String
.
类型的所有属性执行操作
我做不到 this 因为我在对象内部工作 - 不是在外部引用它 - 所以我不明白它是如何工作的。
我直觉上觉得这应该是可能的,但我不能完全理解它的语法。
另一种方法是将它创建为一个独立的函数,你 ref
一个对象,它做同样类型的事情,除了在那种情况下对象会有一个名字。
找到 属性 后,您可以写:
string value = (string)propInfo.GetValue(this);
// manipulate
propInfo.SetValue(this, value);
因此方法可以是:
public void Sanitize()
{
var CheckItemType = typeof(SpecialClass);
var strType = typeof(string);
var propInfos = CheckItemType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach ( var propInfo in propInfos )
if ( propInfo.PropertyType == strType && propInfo.CanWrite )
{
string value = (string)propInfo.GetValue(this);
// manipulate
propInfo.SetValue(this, value);
}
}
您也可以使用 Linq:
public void Sanitize()
{
var typeString = typeof(string);
var propertiesInfos = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.PropertyType == typeString
&& p.CanWrite
&& p.CanRead);
foreach ( var propertyInfo in propertiesInfos )
{
string value = (string)propertyInfo.GetValue(this);
// manipulate
propertyInfo.SetValue(this, value);
}
}
在这里我们解析实例(this)属性,而不是静态的...所以你可以看到@DmitryBychenko 的回答来考虑它们并通过添加 null
而不是静态成员上的 this
BindingFlags.Static
到 select 如果需要的话。
我会做这样的事情。
SpecialClass sc = new SpecialClass()
{
MyString1 = "abc",
MyString2 = "xyz"
};
Sanitize(sc);
以及 Sanitize 方法。
public void Sanitize(object obj)
{
//loop all the propterties
foreach (PropertyInfo propInfo in obj.GetType().GetProperties())
{
//check if the property is a string
if (propInfo.PropertyType != typeof(System.String))
continue;
//get the value
string value = (string)propInfo.GetValue(obj, null);
value = value + "_TEST";
//set the value
propInfo.SetValue(obj, value);
}
}
我建议使用 Linq 以便 查询 类型并获得所需的属性:
var properties = GetType() // current type
.GetProperties(BindingFlags.Public | BindingFlags.Instance) // public, not static
.Where(p => p.CanRead && p.CanWrite) // can read and write
.Where(p => !p.GetIndexParameters().Any()) // not indexer
.Where(p => p.PropertyType == typeof(string)); // of type string
然后在 foreach
循环中分析这些属性及其值,如下所示:
using System.Linq;
using System.Reflection;
...
public void Sanitize() {
var properties = GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanRead && p.CanWrite)
.Where(p => !p.GetIndexParameters().Any())
.Where(p => p.PropertyType == typeof(string));
foreach (PropertyInfo prop in properties) {
// just for reference: if you want to include static properties
// you'll have to put null as instance
object target = prop.GetGetMethod().IsStatic ? null : this;
// current property value
string value = prop.GetValue(target) as String;
//ToDo: Put relevant code here
string someModifiedValue = value + "_modified";
// Write, if required
prop.SetValue(target, someModifiedValue);
}
}
我需要遍历一个项目的所有 String
属性,检索它们的值,并操纵这些值——不需要知道项目的名称或 属性 本身。到目前为止,我看到的所有 SetValue
示例都假设您知道 属性 的名称,并使用该名称来引用它。在我的例子中,我没有按名称调用任何东西,而是简单地遍历每个字符串。
public class SpecialClass
{
public string MyString1 { get; set; }
public string MyString2 { get; set; }
public void Sanitize()
{
Type CheckItemType = typeof(SpecialClass);
Type strType = typeof(System.String);
PropertyInfo[] propInfos = CheckItemType.GetProperties(
BindingFlags.Public | BindingFlags.Instance);
foreach (var propInfo in propInfos)
{
if (null != propInfo && propInfo.CanWrite)
{
if (propInfo.PropertyType == typeof(System.String))
{
// Retrieve the value of the string, manipulate, and then set it
}
}
}
}
}
在上面的代码中,Sanitize
方法将循环遍历 class 中的字符串,并在满足特定条件时调整它们的值。
虽然我找到了 this post,但它描述的内容似乎要求您知道项目的名称和 属性。就我而言,我也不知道。我有一个方法,其目的是对 String
.
我做不到 this 因为我在对象内部工作 - 不是在外部引用它 - 所以我不明白它是如何工作的。
我直觉上觉得这应该是可能的,但我不能完全理解它的语法。
另一种方法是将它创建为一个独立的函数,你 ref
一个对象,它做同样类型的事情,除了在那种情况下对象会有一个名字。
找到 属性 后,您可以写:
string value = (string)propInfo.GetValue(this);
// manipulate
propInfo.SetValue(this, value);
因此方法可以是:
public void Sanitize()
{
var CheckItemType = typeof(SpecialClass);
var strType = typeof(string);
var propInfos = CheckItemType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach ( var propInfo in propInfos )
if ( propInfo.PropertyType == strType && propInfo.CanWrite )
{
string value = (string)propInfo.GetValue(this);
// manipulate
propInfo.SetValue(this, value);
}
}
您也可以使用 Linq:
public void Sanitize()
{
var typeString = typeof(string);
var propertiesInfos = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.PropertyType == typeString
&& p.CanWrite
&& p.CanRead);
foreach ( var propertyInfo in propertiesInfos )
{
string value = (string)propertyInfo.GetValue(this);
// manipulate
propertyInfo.SetValue(this, value);
}
}
在这里我们解析实例(this)属性,而不是静态的...所以你可以看到@DmitryBychenko 的回答来考虑它们并通过添加 null
而不是静态成员上的 this
BindingFlags.Static
到 select 如果需要的话。
我会做这样的事情。
SpecialClass sc = new SpecialClass()
{
MyString1 = "abc",
MyString2 = "xyz"
};
Sanitize(sc);
以及 Sanitize 方法。
public void Sanitize(object obj)
{
//loop all the propterties
foreach (PropertyInfo propInfo in obj.GetType().GetProperties())
{
//check if the property is a string
if (propInfo.PropertyType != typeof(System.String))
continue;
//get the value
string value = (string)propInfo.GetValue(obj, null);
value = value + "_TEST";
//set the value
propInfo.SetValue(obj, value);
}
}
我建议使用 Linq 以便 查询 类型并获得所需的属性:
var properties = GetType() // current type
.GetProperties(BindingFlags.Public | BindingFlags.Instance) // public, not static
.Where(p => p.CanRead && p.CanWrite) // can read and write
.Where(p => !p.GetIndexParameters().Any()) // not indexer
.Where(p => p.PropertyType == typeof(string)); // of type string
然后在 foreach
循环中分析这些属性及其值,如下所示:
using System.Linq;
using System.Reflection;
...
public void Sanitize() {
var properties = GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanRead && p.CanWrite)
.Where(p => !p.GetIndexParameters().Any())
.Where(p => p.PropertyType == typeof(string));
foreach (PropertyInfo prop in properties) {
// just for reference: if you want to include static properties
// you'll have to put null as instance
object target = prop.GetGetMethod().IsStatic ? null : this;
// current property value
string value = prop.GetValue(target) as String;
//ToDo: Put relevant code here
string someModifiedValue = value + "_modified";
// Write, if required
prop.SetValue(target, someModifiedValue);
}
}