C#:如何获取types的所有公共(包括get和set)string属性

我试图做一个方法,将通过通用对象的列表,并replace所有他们的属性typesstringnull或空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.Instancefind属性 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属性