Ustaw właściwość obiektu za pomocą odbicia
Czy Jest jakiś sposób w C# 3.5 gdzie mogę użyć reflection aby ustawić właściwość obiektu?
Ex:
MyObject obj = new MyObject();
obj.Name = "Value";
Chcę ustawić obj.Name
z refleksją. Coś w stylu:
Reflection.SetProperty(obj, "Name") = "Value";
Jest na to jakiś sposób? 11 answers
Tak, możesz użyć Type.InvokeMember()
:
using System.Reflection;
MyObject obj = new MyObject();
obj.GetType().InvokeMember("Name",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
Type.DefaultBinder, obj, "Value");
Spowoduje wyrzucenie wyjątku, jeśli obj
nie ma właściwości o nazwie Name
lub nie można jej ustawić.
Innym sposobem jest pobranie metadanych właściwości, a następnie jej ustawienie. To pozwoli Ci sprawdzić istnienie właściwości i sprawdzić, czy można ją ustawić:
using System.Reflection;
MyObject obj = new MyObject();
PropertyInfo prop = obj.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);
if(null != prop && prop.CanWrite)
{
prop.SetValue(obj, "Value", null);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-09 20:22:06
Możesz również zrobić:
Type type = target.GetType();
PropertyInfo prop = type.GetProperty("propertyName");
prop.SetValue (target, propertyValue, null);
Gdzie target jest obiektem, który będzie miał ustawioną właściwość.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-06 17:55:33
Odbicie, czyli w zasadzie
myObject.GetType().GetProperty(property).SetValue(myObject, "Bob", null);
Lub istnieją biblioteki, które pomagają zarówno pod względem wygody, jak i wydajności; na przykład z FastMember :
var wrapped = ObjectAccessor.Create(obj);
wrapped[property] = "Bob";
(który również ma tę zaletę, że nie musi wiedzieć z góry, czy jest to pole a własność)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-20 14:05:09
Albo możesz owinąć jedną liner Marc ' a wewnątrz swojej własnej klasy extension:
public static class PropertyExtension{
public static void SetPropertyValue(this object obj, string propName, object value)
{
obj.GetType().GetProperty(propName).SetValue(obj, value, null);
}
}
I nazwij to tak:
myObject.SetPropertyValue("myProperty", "myValue");
Dla dobrej miary, dodajmy metodę, aby uzyskać wartość właściwości:
public static object GetPropertyValue(this object obj, string propName)
{
return obj.GetType().GetProperty(propName).GetValue (obj, null);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-20 21:44:05
Tak, używając System.Reflection
:
using System.Reflection;
...
string prop = "name";
PropertyInfo pi = myObject.GetType().GetProperty(prop);
pi.SetValue(myObject, "Bob", null);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-21 13:49:35
Możesz również uzyskać dostęp do pól używając simillar:
var obj=new MyObject();
FieldInfo fi = obj.GetType().
GetField("Name", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue(obj,value)
Z refleksją wszystko może być otwartą książką:) w moim przykładzie wiążemy się z prywatnym polem poziomu instancji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-06 18:00:20
Użyj czegoś takiego:
public static class PropertyExtension{
public static void SetPropertyValue(this object p_object, string p_propertyName, object value)
{
PropertyInfo property = p_object.GetType().GetProperty(p_propertyName);
property.SetValue(p_object, Convert.ChangeType(value, property.PropertyType), null);
}
}
Lub
public static class PropertyExtension{
public static void SetPropertyValue(this object p_object, string p_propertyName, object value)
{
PropertyInfo property = p_object.GetType().GetProperty(p_propertyName);
Type t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
object safeValue = (value == null) ? null : Convert.ChangeType(value, t);
property.SetValue(p_object, safeValue, null);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-03 10:11:01
Możesz to wypróbować, gdy chcesz masowo przypisać właściwości obiektu z innego obiektu za pomocą nazw właściwości:
public static void Assign(this object destination, object source)
{
if (destination is IEnumerable && source is IEnumerable)
{
var dest_enumerator = (destination as IEnumerable).GetEnumerator();
var src_enumerator = (source as IEnumerable).GetEnumerator();
while (dest_enumerator.MoveNext() && src_enumerator.MoveNext())
dest_enumerator.Current.Assign(src_enumerator.Current);
}
else
{
var destProperties = destination.GetType().GetProperties();
foreach (var sourceProperty in source.GetType().GetProperties())
{
foreach (var destProperty in destProperties)
{
if (destProperty.Name == sourceProperty.Name && destProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
{
destProperty.SetValue(destination, sourceProperty.GetValue(source, new object[] { }), new object[] { });
break;
}
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-20 18:35:41
Właśnie opublikowałem pakiet Nuget, który umożliwia ustawienie nie tylko właściwości pierwszego poziomu, ale także właściwości zagnieżdżonych w danym obiekcie w dowolnej głębi.
Oto pakiet
Ustawia wartość właściwości obiektu według jego ścieżki z katalogu głównego.
Obiekt może być obiektem złożonym, a właściwość może być wielopoziomową, głęboką zagnieżdżoną właściwością lub może być właściwością bezpośrednio pod rootem. ObjectWriter
znajdzie nieruchomość korzystając z nieruchomości parametr ścieżki i zaktualizuj jego wartość. Ścieżka właściwości to dołączone nazwy właściwości odwiedzanych od root do właściwości węzła końcowego, które chcemy ustawić, oddzielone przez parametr delimiter string.
Użycie:
Do Ustawienia Właściwości bezpośrednio pod głównym obiektem:
Ie. LineItem
klasa ma właściwość int o nazwie ItemId
LineItem lineItem = new LineItem();
ObjectWriter.Set(lineItem, "ItemId", 13, delimiter: null);
Do Ustawienia zagnieżdżonej właściwości wielu poziomów poniżej głównego obiektu:
Ie. Invite
klasa ma właściwość o nazwie State
, która ma właściwość o nazwie Invite
(Typu Invite), która ma właściwość o nazwie Recipient
, która ma właściwość o nazwie Id
.
Aby uczynić rzeczy jeszcze bardziej złożonymi, właściwość State
nie jest typem odniesienia, jest struct
.
Oto jak można ustawić właściwość Id (na wartość string "outlook") na dole drzewa obiektów w jednej linii.
Invite invite = new Invite();
ObjectWriter.Set(invite, "State_Invite_Recipient_Id", "outlook", delimiter: "_");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-24 18:25:15
Bazując na sugestii Marcgravella, skonstruowałem następującą metodę statyczną.Metoda ogólnie przypisuje wszystkie pasujące właściwości z obiektu źródłowego do celu za pomocą FastMember
public static void DynamicPropertySet(object source, object target)
{
//SOURCE
var src_accessor = TypeAccessor.Create(source.GetType());
if (src_accessor == null)
{
throw new ApplicationException("Could not create accessor!");
}
var src_members = src_accessor.GetMembers();
if (src_members == null)
{
throw new ApplicationException("Could not fetch members!");
}
var src_class_members = src_members.Where(x => x.Type.IsClass && !x.Type.IsPrimitive);
var src_class_propNames = src_class_members.Select(x => x.Name);
var src_propNames = src_members.Except(src_class_members).Select(x => x.Name);
//TARGET
var trg_accessor = TypeAccessor.Create(target.GetType());
if (trg_accessor == null)
{
throw new ApplicationException("Could not create accessor!");
}
var trg_members = trg_accessor.GetMembers();
if (trg_members == null)
{
throw new ApplicationException("Could not create accessor!");
}
var trg_class_members = trg_members.Where(x => x.Type.IsClass && !x.Type.IsPrimitive);
var trg_class_propNames = trg_class_members.Select(x => x.Name);
var trg_propNames = trg_members.Except(trg_class_members).Select(x => x.Name);
var class_propNames = trg_class_propNames.Intersect(src_class_propNames);
var propNames = trg_propNames.Intersect(src_propNames);
foreach (var propName in propNames)
{
trg_accessor[target, propName] = src_accessor[source, propName];
}
foreach (var member in class_propNames)
{
var src = src_accessor[source, member];
var trg = trg_accessor[target, member];
if (src != null && trg != null)
{
DynamicPropertySet(src, trg);
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-15 15:06:03
Mogę ustawić właściwość klasy używając reflection, gdzie moje właściwości klasy są tylko ciągiem znaków. Teraz muszę wprowadzić jeden słownik jako członek tej klasy, ale nie mogę ustawić wartości. Używam poniższego fragmentu kodu dla właściwości string.
object objval;
objval=System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(className);
objval.GetType().GetProperty(classpropertyname).SetValue(objval,Value);
Jak ustawić wartość słownika za pomocą odbicia
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-20 05:50:36