알 수없는 객체에서 속성 및 값 가져 오기


150

PHP 세계에서 나는 C #을 사용하기로 결정했습니다. 나는 검색을했지만 이것과 동등한 것을하는 방법에 대한 대답을 찾지 못하는 것 같습니다.

$object = new Object();

$vars = get_class_vars(get_class($object));

foreach($vars as $var)
{
    doSomething($object->$var);
}

기본적으로 객체 목록이 있습니다. 개체는 세 가지 유형 중 하나 일 수 있으며 일련의 공용 속성을 갖습니다. 객체의 속성 목록을 가져 와서 루프로 묶은 다음 파일에 쓸 수 있기를 원합니다. 나는 이것이 C # 리플렉션과 관련이 있다고 생각하지만 그것은 모두 나에게 새로운 것입니다.

도움을 주시면 감사하겠습니다.


9
참고 사항 : 공통 기본 클래스 또는 인터페이스가없는 목록에 다른 유형의 객체를 갖는 것은 적어도 C #에서는 좋지 않은 프로그래밍 스타일이 아닙니다.
Albin Sunnanbo

답변:


284

이것은해야합니다 :

Type myType = myObject.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());

foreach (PropertyInfo prop in props)
{
    object propValue = prop.GetValue(myObject, null);

    // Do something with propValue
}

PropertyInfo는 어디에서 왔습니까?
Jonathan dos Santos

8
@jonathan System.Reflection네임 스페이스
Cocowalla

21
실제로 배열에서 목록을 만들 필요는 없습니다.PropertyInfo[] props = input.GetType().GetProperties();
VladL

2
Newtonsoft.Json.JsonConvert?를 사용하여 2017 답변을 업데이트 하시겠습니까?
Vayne

1
@clone 그것은 완전히 다른 방법입니다. 그것이 올바른 접근이라고 생각되면 답변을 게시해야합니다
Cocowalla

23
void Test(){
    var obj = new{a="aaa", b="bbb"};

    var val_a = obj.GetValObjDy("a"); //="aaa"
    var val_b = obj.GetValObjDy("b"); //="bbb"
}
//create in a static class
static public object GetValObjDy(this object obj, string propertyName)
{            
     return obj.GetType().GetProperty(propertyName).GetValue(obj, null);
}

17

그렇습니다. 리플렉션은 갈 길입니다. 먼저 Type목록에서 인스턴스의 유형 (런타임)을 나타내는를 얻습니다 . GetTypeon 메소드를Object 호출하여이를 수행 할 수 있습니다 . Object클래스 에 있기 때문에 모든 유형에서 파생되므로 .NET의 모든 객체에서 호출 할 수 있습니다 Object( 기술적으로는 모든 것이 아니지만 중요하지는 않습니다).

당신은 일단 Type인스턴스를, 당신은 호출 할 수있는 GetProperties방법을 얻가에 PropertyInfo온 속성에 대한 런타임 informationa을 나타내는 인스턴스 Type.

오버로드를 사용하여 검색 속성을 GetProperties분류 할 수 있습니다 .

거기에서 정보를 파일로 작성하면됩니다.

위의 코드는 다음과 같습니다.

// The instance, it can be of any type.
object o = <some object>;

// Get the type.
Type type = o.GetType();

// Get all public instance properties.
// Use the override if you want to classify
// which properties to return.
foreach (PropertyInfo info in type.GetProperties())
{
    // Do something with the property info.
    DoSomething(info);
}

메소드 정보 또는 필드 정보를 원하는 경우 GetMethods또는 GetFields메소드 의 과부하 중 하나를 각각 호출해야합니다 .

또한 멤버를 파일에 나열하는 것이 중요하지만 이 정보를 사용하여 속성 세트를 기반으로 논리를 구동 해서는 안됩니다 .

유형의 구현을 제어한다고 가정하면 공통 기본 클래스에서 파생되거나 공통 인터페이스를 구현하고 해당 인터페이스를 호출해야합니다 ( as또는 is연산자를 사용하여 작업중인 기본 클래스 / 인터페이스를 판별 할 수 있음) 실행 시간).

그러나 이러한 유형 정의를 제어하지 않고 패턴 일치를 기반으로 논리를 구동해야한다면 괜찮습니다.


11

음, C #에서도 비슷합니다. 다음은 가장 간단한 예 중 하나입니다 (공공 재산에만 해당).

var someObject = new { .../*properties*/... };
var propertyInfos = someObject.GetType().GetProperties();
foreach (PropertyInfo pInfo in PropertyInfos)
{
    string propertyName = pInfo.Name; //gets the name of the property
    doSomething(pInfo.GetValue(someObject,null));
}

9

속성 이름에서 특정 속성 값을 가져 오려면

public class Bike{
public string Name {get;set;}
}

Bike b = new Bike {Name = "MyBike"};

문자열의 속성 이름에서 Name의 속성 값에 액세스

public object GetPropertyValue(string propertyName)
{
//returns value of property Name
return this.GetType().GetProperty(propertyName).GetValue(this, null);
} 

3

GetType-GetProperties-Linq Foreach를 사용할 수 있습니다 .

obj.GetType().GetProperties().ToList().ForEach(p =>{
                                                        //p is each PropertyInfo
                                                        DoSomething(p);
                                                    });

3

Linq를 사용한 한 라인 솔루션 ...

var obj = new {Property1: 1, Property2: 2};
var property1 = obj.GetType().GetProperties().First(o => o.Name == "Property1").GetValue(obj , null);

2

다음은 의 속성을 나타내는 열을 포함 하는 IEnumerable<T>로 변환하는 데 사용하는 항목입니다 .DataTableTIEnumerable

public static DataTable ToDataTable<T>(IEnumerable<T> items)
{
    var table = CreateDataTableForPropertiesOfType<T>();
    PropertyInfo[] piT = typeof(T).GetProperties();
    foreach (var item in items)
    {
        var dr = table.NewRow();
        for (int property = 0; property < table.Columns.Count; property++)
        {
            if (piT[property].CanRead)
            {
                var value = piT[property].GetValue(item, null);
                if (piT[property].PropertyType.IsGenericType)
                {
                    if (value == null)
                    {
                        dr[property] = DBNull.Value;
                    }
                    else
                    {
                        dr[property] = piT[property].GetValue(item, null);
                    }
                }
                else
                {
                    dr[property] = piT[property].GetValue(item, null);
                }
            }
        }
        table.Rows.Add(dr);
    }
    return table;
}

public static DataTable CreateDataTableForPropertiesOfType<T>()
{
    DataTable dt = new DataTable();
    PropertyInfo[] piT = typeof(T).GetProperties();
    foreach (PropertyInfo pi in piT)
    {
        Type propertyType = null;
        if (pi.PropertyType.IsGenericType)
        {
            propertyType = pi.PropertyType.GetGenericArguments()[0];
        }
        else
        {
            propertyType = pi.PropertyType;
        }
        DataColumn dc = new DataColumn(pi.Name, propertyType);

        if (pi.CanRead)
        {
            dt.Columns.Add(dc);
        }
    }
    return dt;
}

이것은 "약간"복잡하지만, 실제로는 다음과 같이 결과를 볼 수 있습니다 List<T>. 예를 들면 다음과 같습니다.

public class Car
{
    string Make { get; set; }
    int YearOfManufacture {get; set; }
}

그리고 다음 구조를 가진 DataTable이 반환됩니다.

Make (문자열)
YearOfManufacture (int)

귀하의 항목 당 하나의 행으로 List<Car>


1

이 예제는 객체의 모든 문자열 속성을 잘라냅니다.

public static void TrimModelProperties(Type type, object obj)
{
    var propertyInfoArray = type.GetProperties(
                                    BindingFlags.Public | 
                                    BindingFlags.Instance);
    foreach (var propertyInfo in propertyInfoArray)
    {
        var propValue = propertyInfo.GetValue(obj, null);
        if (propValue == null) 
            continue;
        if (propValue.GetType().Name == "String")
            propertyInfo.SetValue(
                             obj, 
                             ((string)propValue).Trim(), 
                             null);
    }
}

0

Application 객체와 같이 작동하지 않습니다. 그러나 나는 성공했다

var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();

string rval = serializer.Serialize(myAppObj);

2
피할 수 있으면 JavaScriptSerializer를 사용하지 마십시오. 많은 이유가 있습니다.
Nuno André

0
public Dictionary<string, string> ToDictionary(object obj)
{
    Dictionary<string, string> dictionary = new Dictionary<string, string>();

    Type objectType = obj.GetType();
    IList<PropertyInfo> props = new List<PropertyInfo>(objectType.GetProperties());

    foreach (PropertyInfo prop in props)
    {
        object propValue = prop.GetValue(obj, null);
        dictionary.Add(prop.Name, propValue.ToString());
    }

    return dictionary;
}

0
    /// get set value field in object to object new (two object  field like ) 

    public static void SetValueObjectToObject (object sourceObj , object resultObj)
    {
        IList<PropertyInfo> props = new List<PropertyInfo>(sourceObj.GetType().GetProperties());
        foreach (PropertyInfo prop in props)
        {
            try
            {
                //get value in sourceObj
                object propValue = prop.GetValue(sourceObj, null);
                //set value in resultObj
                PropertyInfo propResult = resultObj.GetType().GetProperty(prop.Name, BindingFlags.Public | BindingFlags.Instance);
                if (propResult != null && propResult.CanWrite)
                {
                    propResult.SetValue(resultObj, propValue, null);
                }
            }
            catch (Exception ex)
            {  
                // do something with Ex
            }
        }
    }

-1

당신은 이것을 시도 할 수 있습니다 :

string[] arr = ((IEnumerable)obj).Cast<object>()
                                 .Select(x => x.ToString())
                                 .ToArray();

모든 배열이 IEnumerable 인터페이스를 구현하면

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.