C#:如何获取types的所有公共(包括get和set)string属性
我试图做一个方法,将通过通用对象的列表,并replace所有他们的属性typesstring
是null
或空replace。
如何做到这一点的好方法?
我有这种…壳…迄今:
public static void ReplaceEmptyStrings<T>(List<T> list, string replacement) { var properties = typeof(T).GetProperties( -- What BindingFlags? -- ); foreach(var p in properties) { foreach(var item in list) { if(string.IsNullOrEmpty((string) p.GetValue(item, null))) p.SetValue(item, replacement, null); } } }
那么,我如何find一个types的所有属性:
-
string
的types - 公众
get
-
有公共
set
?
我做了这个testing课:
class TestSubject { public string Public; private string Private; public string PublicPublic { get; set; } public string PublicPrivate { get; private set; } public string PrivatePublic { private get; set; } private string PrivatePrivate { get; set; } }
以下不起作用:
var properties = typeof(TestSubject) .GetProperties(BindingFlags.Instance|BindingFlags.Public) .Where(ø => ø.CanRead && ø.CanWrite) .Where(ø => ø.PropertyType == typeof(string));
如果我打印出那些属性的名称,我会得到:
公共公共私有私有公共
换句话说,我得到两个属性太多了。
注意 :这可能是一个更好的方法…使用嵌套的foreach和reflection和所有这里…但如果你有任何伟大的替代想法,请让我知道,因为我想学习!
您的代码被重写。 不使用LINQ或var。
public static void ReplaceEmptyStrings<T>(List<T> list, string replacement) { PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (PropertyInfo p in properties) { // Only work with strings if (p.PropertyType != typeof(string)) { continue; } // If not writable then cannot null it; if not readable then cannot check it's value if (!p.CanWrite || !p.CanRead) { continue; } MethodInfo mget = p.GetGetMethod(false); MethodInfo mset = p.GetSetMethod(false); // Get and set methods have to be public if (mget == null) { continue; } if (mset == null) { continue; } foreach (T item in list) { if (string.IsNullOrEmpty((string)p.GetValue(item, null))) { p.SetValue(item, replacement, null); } } } }
你可以通过BindingFlags.Public | BindingFlags.Instance
find属性 BindingFlags.Public | BindingFlags.Instance
。 然后,您将需要通过检查CanWrite和CanRead属性来检查每个PropertyInfo实例,以确定它们是否可读和/或可写。
更新:代码示例
PropertyInfo[] props = yourClassInstance.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); for (int i = 0; i < props.Length; i++) { if (props[i].PropertyType == typeof(string) && props[i].CanWrite) { // do your update } }
更新之后,我会更详细地研究它。 如果你也检查由GetGetMethod和GetSetMethod返回的MethodInfo对象,你会打到目标,我想;
var properties = typeof(TestSubject).GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(ø => ø.CanRead && ø.CanWrite) .Where(ø => ø.PropertyType == typeof(string)) .Where(ø => ø.GetGetMethod(true).IsPublic) .Where(ø => ø.GetSetMethod(true).IsPublic);
默认情况下,这两个方法只返回公有的getter和setter(在这种情况下冒着NullReferenceException风险),但是如上所述传递true
也会返回私有的。 然后,您可以检查IsPublic
(或IsPrivate
)属性。
如果你不指定任何绑定标志,你将获得公共的实例属性 – 这是你想要的。 但是,那么您将需要检查PropertyInfo对象的PropertyType是否为Stringtypes。 除非事先知道,否则您还需要检查属性是否可读/写,如@Fredrik所示。
using System.Linq; public static void ReplaceEmptyStrings<T>(List<T> list, string replacement) { var properties = typeof(T).GetProperties() .Where( p => p.PropertyType == typeof(string) ); foreach(var p in properties) { foreach(var item in list) { if(string.IsNullOrEmpty((string) p.GetValue(item, null))) p.SetValue(item, replacement, null); } } }
http://jefferytay.wordpress.com/2010/05/03/simple-and-useful-tostring/
对于一个tostring覆盖方法,它允许你获得该类的所有属性
BindingFlags.Public | BindingFlags.Instance应该这样做
GetSetMethod()
我build议一个不同的方法: AOP 。
您可以拦截setter并将所需值设置为有效值。 使用PostSharp很容易。
我同意其他的答案,但我更喜欢重构search本身与Linq轻松查询,所以查询可以如下:
var asm = Assembly.GetExecutingAssembly(); var properties = (from prop in asm.GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance) where prop.PropertyType == typeof (string) && prop.CanWrite && prop.CanRead select prop).ToList(); properties.ForEach(p => Debug.WriteLine(p.Name));
我拿我的例子的Assemblytypes,它没有读/写string属性,但如果相同的代码search只读属性,结果将是:
- 基本代码
- EscapedCodeBase
- 全名
- 位置
- ImageRuntimeVersion
哪些是string 只读的组件types属性