C # : 형식의 모든 공용 (가져 오기 및 설정 모두) 문자열 속성을 가져 오는 방법
나는 일반 객체의 목록을 가서 유형의 모든 속성을 대체 할 방법을 만들려고 노력하고 있어요 string
중 하나입니다 null
또는 교체 빈을.
이 작업을 수행하는 좋은 방법은 무엇입니까?
나는 이런 종류의 ... 껍질 ... 지금까지 :
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);
}
}
}
따라서 다음과 같은 유형의 모든 속성을 어떻게 찾을 수 있습니까?
- 유형
string
- 공개
get
공개
set
?
이 테스트 클래스를 만들었습니다.
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 및 반사를 사용하여 여기에 모두 ...하지만 훌륭한 대안 아이디어가 있으면 배우고 싶은 이유를 알려주십시오!
코드를 다시 작성했습니다. 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);
}
}
}
}
.NET과 같은 속성을 찾을 수 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
) 속성을 검사 할 수 있습니다.
If you don't specify any binding flags you will get the public, instance properties -- which is what you want. But then you will need to check if the PropertyType on the PropertyInfo object is of type String. Unless you know in advance, you'll also need to check whether the property is readable/writable as @Fredrik indicates.
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/
for a tostring override method which allows you to get all the properties of the class
BindingFlags.Public | BindingFlags.Instance should do it
GetSetMethod()
I suggest a different approach: AOP.
You can intercept the setter and set the desired value to a valid one. With PostSharp it's quite easy.
I agree with other answers, but I prefer to refactor the search itself to be easly queried with Linq, so the query could be as follow:
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));
I took for my example the Assembly type, which hasn't read/write string properties, but if the same code search for just read properties, the result will be:
- CodeBase
- EscapedCodeBase
- FullName
- Location
- ImageRuntimeVersion
Which are the string read-only Assembly type properties
ReferenceURL : https://stackoverflow.com/questions/824802/c-how-to-get-all-public-both-get-and-set-string-properties-of-a-type
'programing' 카테고리의 다른 글
Python 3.x에서 2.x와 유사한 정렬 동작을 얻으려면 어떻게해야합니까? (0) | 2021.01.15 |
---|---|
Swift의 일반 유형 별칭 (0) | 2021.01.15 |
python / matplotlib의 세로 레이블이있는 Barchart (0) | 2021.01.14 |
Perl이 설치되지 않은 시스템에서 실행될 수 있도록 Perl 스크립트를 컴파일하려면 어떻게해야합니까? (0) | 2021.01.14 |
크로스 플랫폼 Qt 애플리케이션에 모노 스페이스 글꼴을 지정하는 방법은 무엇입니까? (0) | 2021.01.14 |