net - property c# get set example




Ottieni il valore della proprietà da una stringa usando la riflessione in C# (14)

Aggiungi a qualsiasi Class :

public class Foo
{
    public object this[string propertyName]
    {
        get { return this.GetType().GetProperty(propertyName).GetValue(this, null); }
        set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); }
    }

    public string Bar { get; set; }
}

Quindi, puoi usare come:

Foo f = new Foo();
// Set
f["Bar"] = "asdf";
// Get
string s = (string)f["Bar"];

Sto provando a implementare la trasformazione dei dati utilizzando l' esempio di Reflection 1 nel mio codice.

La funzione GetSourceValue ha uno switch che confronta vari tipi, ma voglio rimuovere questi tipi e proprietà e avere GetSourceValue ottenere il valore della proprietà usando solo una singola stringa come parametro. Voglio passare una classe e una proprietà nella stringa e risolvere il valore della proprietà.

È possibile?

1 versione Web Archive del post originale del blog


Che dire dell'utilizzo del CallByName dello spazio dei nomi Microsoft.VisualBasic.dll ( Microsoft.VisualBasic.dll )? Usa la riflessione per ottenere proprietà, campi e metodi di oggetti normali, oggetti COM e persino oggetti dinamici.

using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;

e poi

Versioned.CallByName(this, "method/function/prop name", CallType.Get).ToString();

Ecco la mia soluzione. Funziona anche con oggetti COM e consente di accedere agli elementi raccolta / matrice dagli oggetti COM.

public static object GetPropValue(this object obj, string name)
{
    foreach (string part in name.Split('.'))
    {
        if (obj == null) { return null; }

        Type type = obj.GetType();
        if (type.Name == "__ComObject")
        {
            if (part.Contains('['))
            {
                string partWithoundIndex = part;
                int index = ParseIndexFromPropertyName(ref partWithoundIndex);
                obj = Versioned.CallByName(obj, partWithoundIndex, CallType.Get, index);
            }
            else
            {
                obj = Versioned.CallByName(obj, part, CallType.Get);
            }
        }
        else
        {
            PropertyInfo info = type.GetProperty(part);
            if (info == null) { return null; }
            obj = info.GetValue(obj, null);
        }
    }
    return obj;
}

private static int ParseIndexFromPropertyName(ref string name)
{
    int index = -1;
    int s = name.IndexOf('[') + 1;
    int e = name.IndexOf(']');
    if (e < s)
    {
        throw new ArgumentException();
    }
    string tmp = name.Substring(s, e - s);
    index = Convert.ToInt32(tmp);
    name = name.Substring(0, s - 1);
    return index;
}

Ecco un altro modo per trovare una proprietà nidificata che non richiede la stringa per dirti il ​​percorso di nidificazione. Credito a Ed S. per il metodo della proprietà singola.

    public static T FindNestedPropertyValue<T, N>(N model, string propName) {
        T retVal = default(T);
        bool found = false;

        PropertyInfo[] properties = typeof(N).GetProperties();

        foreach (PropertyInfo property in properties) {
            var currentProperty = property.GetValue(model, null);

            if (!found) {
                try {
                    retVal = GetPropValue<T>(currentProperty, propName);
                    found = true;
                } catch { }
            }
        }

        if (!found) {
            throw new Exception("Unable to find property: " + propName);
        }

        return retVal;
    }

        public static T GetPropValue<T>(object srcObject, string propName) {
        return (T)srcObject.GetType().GetProperty(propName).GetValue(srcObject, null);
    }

Il metodo di chiamata è cambiato in .NET Standard (a partire da 1.6). Inoltre possiamo usare l'operatore condizionale nullo di C # 6.

using System.Reflection; 
public static object GetPropValue(object src, string propName)
{
    return src.GetType().GetRuntimeProperty(propName)?.GetValue(src);
}

Il metodo seguente funziona perfettamente per me:

class MyClass {
    public string prop1 { set; get; }

    public object this[string propertyName]
    {
        get { return this.GetType().GetProperty(propertyName).GetValue(this, null); }
        set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); }
    }
}

Per ottenere il valore della proprietà:

MyClass t1 = new MyClass();
...
string value = t1["prop1].ToString();

Per impostare il valore della proprietà:

t1["prop1] = value;

Informazioni sulla discussione delle proprietà nidificate, è possibile evitare tutte le risorse di riflessione se si utilizza il DataBinder.Eval Method (Object, String) come indicato di seguito:

var value = DataBinder.Eval(DateTime.Now, "TimeOfDay.Hours");

Ovviamente, dovrai aggiungere un riferimento all'assembly System.Web , ma probabilmente non è un grosso problema.


Non hai mai menzionato quale oggetto stai ispezionando, e dal momento che stai rifiutando quelli che fanno riferimento a un dato oggetto, assumerò che tu intenda uno statico.

using System.Reflection;
public object GetPropValue(string prop)
{
    int splitPoint = prop.LastIndexOf('.');
    Type type = Assembly.GetEntryAssembly().GetType(prop.Substring(0, splitPoint));
    object obj = null;
    return type.GetProperty(prop.Substring(splitPoint + 1)).GetValue(obj, null);
}

Si noti che ho contrassegnato l'oggetto che viene ispezionato con la variabile locale obj . null significa statico, altrimenti imposta ciò che desideri. Si noti inoltre che GetEntryAssembly() è uno dei pochi metodi disponibili per ottenere l'assembly "in esecuzione", si potrebbe voler giocare con esso se si sta facendo fatica a caricare il tipo.


Utilizzando PropertyInfo dello spazio dei nomi System.Reflection . Reflection si compila bene indipendentemente dalla proprietà a cui proviamo ad accedere. L'errore si presenterà durante l'esecuzione.

    public static object GetObjProperty(object obj, string property)
    {
        Type t = obj.GetType();
        PropertyInfo p = t.GetProperty("Location");
        Point location = (Point)p.GetValue(obj, null);
        return location;
    }

Funziona bene per ottenere la proprietà Location di un oggetto

Label1.Text = GetObjProperty(button1, "Location").ToString();

Otterremo la posizione: {X = 71, Y = 27} Possiamo anche restituire location.X o location.Y allo stesso modo.


modo più breve ....

var a = new Test { Id = 1 , Name = "A" , date = DateTime.Now};
var b = new Test { Id = 1 , Name = "AXXX", date = DateTime.Now };

var compare = string.Join("",a.GetType().GetProperties().Select(x => x.GetValue(a)).ToArray())==
              string.Join("",b.GetType().GetProperties().Select(x => x.GetValue(b)).ToArray());

jheddings e AlexD entrambi scritto ottime risposte su come risolvere le stringhe di proprietà. Mi piacerebbe buttare il mio nel mix, dal momento che ho scritto una libreria dedicata esattamente per quello scopo.

La principale classe di Pather.CSharp è Resolver . Per impostazione predefinita può risolvere proprietà, array e voci del dizionario.

Quindi, ad esempio, se hai un oggetto come questo

var o = new { Property1 = new { Property2 = "value" } };

e vuoi ottenere Property2 , puoi farlo in questo modo:

IResolver resolver = new Resolver();
var path = "Property1.Property2";
object result = r.Resolve(o, path); 
//=> "value"

Questo è l'esempio più semplice dei percorsi che può risolvere. Se vuoi vedere cos'altro può o come estenderlo, vai alla sua Pather.CSharp .


 public static object GetPropValue(object src, string propName)
 {
     return src.GetType().GetProperty(propName).GetValue(src, null);
 }

Ovviamente, vorrete aggiungere la validazione e quant'altro, ma questo è il succo di ciò.


public class YourClass
{
    //Add below line in your class
    public object this[string propertyName] => GetType().GetProperty(propertyName)?.GetValue(this, null);
    public string SampleProperty { get; set; }
}

//And you can get value of any property like this.
var value = YourClass["SampleProperty"];

public static List<KeyValuePair<string, string>> GetProperties(object item) //where T : class
    {
        var result = new List<KeyValuePair<string, string>>();
        if (item != null)
        {
            var type = item.GetType();
            var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var pi in properties)
            {
                var selfValue = type.GetProperty(pi.Name).GetValue(item, null);
                if (selfValue != null)
                {
                    result.Add(new KeyValuePair<string, string>(pi.Name, selfValue.ToString()));
                }
                else
                {
                    result.Add(new KeyValuePair<string, string>(pi.Name, null));
                }
            }
        }
        return result;
    }

Questo è un modo per ottenere tutte le proprietà con i loro valori in un elenco.





reflection