Bilinmeyen nesneden özellikler ve değerler alma


150

PHP dünyasından C # vermeye karar verdim. Bir arama yaptım ama buna eşdeğer bir şeyin nasıl yapılacağının cevabını bulamıyorum.

$object = new Object();

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

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

Temelde bir nesne listesi var. Nesne üç farklı türden biri olabilir ve bir dizi ortak mülke sahip olacaktır. Nesne için özelliklerin bir listesini almak, onları döngü ve daha sonra bir dosyaya yazmak istiyorum. Bunun c # yansıması ile ilgisi olduğunu düşünüyorum ama hepsi benim için yeni.

Herhangi bir yardım büyük mutluluk duyacağız.


9
Bir yan not olarak: bir listede farklı türden nesnelere sahip olmak (ortak bir temel sınıf veya arabirim olmadan) en azından c # değil, iyi bir programlama stili değildir.
Albin Sunnanbo

Yanıtlar:


284

Bunu yapmalı:

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 nereden geliyor?
Jonathan dos Santos

8
@jonathan System.Reflectionisim
Cocowalla

21
PropertyInfo[] props = input.GetType().GetProperties();
Diziden

2
2017 yanıtını kullanarak güncellemek ister misiniz Newtonsoft.Json.JsonConvert?
Vayne

1
@clone bunu yapmanın tamamen farklı bir yolu. Bunun geçerli bir yaklaşım olduğunu düşünüyorsanız bir cevap göndermelisiniz
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

Evet, Yansıma gitmek için bir yol olurdu. İlk olarak, Typelistenin içinde örneğin türünü (çalışma zamanında) temsil eder. GetTypeYöntemiObject çağırarak bunu yapabilirsiniz . Üzerinde Çünkü Objectsınıfın, bu tarafından çağrılabilir var her her türlü kaynaklanıyor gibi .NET nesne Object( kuyu, teknik olarak değil her şey ama burada önemli değil).

Örneği aldıktan sonra Type, üzerindeki özellikler hakkında çalışma zamanı bilgilerini temsil eden örnekleri almak için GetPropertiesyöntemi çağırabilirsiniz .PropertyInfoType

Hangi özellikleri aldığınızın GetPropertiessınıflandırılmasına yardımcı olması için aşırı yüklerini kullanabilirsiniz .

Oradan, bilgileri bir dosyaya yazmanız yeterlidir.

Yukarıdaki kodunuz çevrildi:

// 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);
}

Yöntem bilgisi veya alan bilgisi istiyorsanız, sırasıyla GetMethodsveya GetFieldsyöntemlerinin aşırı yüklenmelerinden birini çağırmanız gerektiğini unutmayın .

Ayrıca not, bir dosyaya üyelere dışarı listeye bir şey, ama olmamalı özellik setleri dayalı sürücü mantığı bu bilgileri kullanırlar.

Türlerin uygulamaları üzerinde denetiminiz olduğunu varsayarsak, ortak bir temel sınıftan türetmeli veya ortak bir arabirim uygulamalı ve bunlara çağrı yapmalısınız ( hangi temel sınıf / arabirimde çalıştığınızı belirlemenize yardımcı olması için asveya isoperatörünü kullanabilirsiniz . Çalışma süresi).

Ancak, bu tür tanımları denetlemezseniz ve desen eşleşmesine dayalı mantığı çalıştırmanız gerekiyorsa, sorun olmaz.


11

iyi, C # 'da benzer. İşte en basit örneklerden biri (yalnızca kamu mülkleri için):

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

Mülk adından belirli mülk değerini almak için

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

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

özelliğinin dize adından Name özellik değerine erişmek için

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

3

Sen kullanabilirsiniz GetProperties - - GetType Linq forEach :

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

3

Linq kullanarak bir satır çözüm ...

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

2

İşte bir 's özelliklerini temsil eden sütunlar içeren IEnumerable<T>bir dönüştürmek için kullandığım bir şey , bir satırda her öğe için bir satır :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;
}

Bu "biraz" aşırı karmaşıktır, ancak aslında sonucun ne olduğunu görmek için oldukça iyidir List<T>, örneğin:

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

Ayrıca, şu yapıya sahip bir DataTable döndürülür:


Yapım (string) YearOfManufacture (int)

Öğenizdeki öğe başına bir satır ile List<Car>


1

Bu örnek, bir nesnenin tüm dize özelliklerini keser.

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

Uygulama nesneleri için bunun üzerinde çalışmayı bulamadım. Bununla birlikte başarılı oldum

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

string rval = serializer.Serialize(myAppObj);

2
Bundan kaçınabiliyorsanız JavaScriptSerializer'ı kullanmayın. Bunun birçok nedeni var .
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

Bunu deneyebilirsiniz:

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

Her dizi IEnumerable arabirimini uyguladığında

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.