Dynamically Reading a Class Property in C#

Y'all must Sign In to use this bulletin board.

Question Does not work for virtual property overrides Pin

Member 3677619 xviii-Apr-xiii 8:24

Member Fellow member 3677619 18-Apr-13 eight:24
PropertyAccessor fails when trying to dynamically read a property that overrides a virtual holding in a base grade. Error message: "Operation could destablize the runtime". Please advise.
Question Magnifying Property Access Pin

ExcellentOrg 7-Apr-13 eleven:37

Member ExcellentOrg 7-Apr-13 11:37
If I wanted to use this to access many different classes (all of which use reflection), should I create a carve up form or somehow add this to the base course?

What I am trying to ask is best possible strategy

Socket Rocket


Suggestion Using of Generics Pin

lordkbc 27-Jun-eleven 2:16

Member lordkbc 27-Jun-eleven 2:16
Hi,

Accept a look on my code. Its use generics to convert parameters and return values. Is limited to classes, structs will not work, interfaces should be work but is not implemented.
Is for read only simply tin be implemented to write likewise.

I believe that is faster because we don't need emit assemblies. What you call up about?

using System;
using System.Collections.Generic;
using System.Linq;
using Arrangement.Text;
using System.Reflection;

namespace ConsoleApplication8
{
grade Program
{
static void Main(string[] args)
{
var examination = new { asValue = 17, asRef = "test" };
var reader = PropertyToDelegate.CreateDelegate(examination, test.GetType().GetProperty("asValue").GetGetMethod());
Console.WriteLine(reader(test));
reader = PropertyToDelegate.CreateDelegate(test, test.GetType().GetProperty("asRef").GetGetMethod());
Console.WriteLine(reader(test));
// or
var blazon = test.GetType();
reader = PropertyToDelegate.CreateDelegate(type, type.GetProperty("asValue").GetGetMethod());
Console.WriteLine(reader(exam));
reader = PropertyToDelegate.CreateDelegate(blazon, blazon.GetProperty("asRef").GetGetMethod());
Console.WriteLine(reader(test));
Console.ReadLine();
}
}

struct structTest
{
public int AsValue { go; set; }
public string AsRef { get; prepare; }
}

public consul object Reader(object This);

static grade PropertyToDelegate
{
public static Reader CreateDelegate<T>(T obj, MethodInfo method) where T : course
{
return PropertyToDelegate<T>.CreateDelegate(method);
}

public static Reader CreateDelegate(Type type, MethodInfo method)
{
return (Reader) typeof(PropertyToDelegate<>).MakeGenericType(type).GetMethod("CreateDelegate").Invoke(null, new object[] { method });
}
}

public static class PropertyToDelegate<T> where T : course
{
public delegate object TReader(T This);
static class BoxerForStructs<South> where S : struct
{
delegate S structReader(T obj);
public static TReader CreateDelegate(MethodInfo method)
{
var del = (structReader)Delegate.CreateDelegate(typeof(structReader), method);
return (T obj) => del(obj);
}
}

public static Reader CreateDelegate(MethodInfo method)
{
TReader del;
if (!method.ReturnType.IsValueType)
del = (TReader)Delegate.CreateDelegate(typeof(TReader), method);
else
del = (TReader)typeof(BoxerForStructs<>).MakeGenericType(typeof(T), method.ReturnType).GetMethod("CreateDelegate").Invoke(null, new object[] { method });
return (This) => del((T)This);
}
}
}

General Just idea I'll mention this Pin

Martin Lottering 17-May-xi 3:06

Member Martin Lottering 17-May-11 three:06
Hi James,

I know this is an old thread, merely I thought I'll simply make an ascertainment for those who care to read reviews:

i. In SampleApp.cs, if I replace the Blazon.InvokeMember() calls with PropertyInfo.SetValue() and PropertyInfo.GetValue(), those durations are sliced to about 20% - 40% of the original time, provided you lot set the PropertyInfo one time Earlier the loop begins. I suppose information technology is because information technology doesn't have to lookup the property info 1,000,000 times every bit done in Type.InvokeMember() in the test app.

What this means is that the REFLECTION part of the examination, which is the slowest, is not optimal.

ii. If like me, yous examination the code provided by Tobi (Mr T#), and the generic implementation seems slower, it is only considering he used 100,000,000 test cycles instead of 1,000,000 as used by James.

BTW, smashing article, and great code. Very useful. Thanks.

Regards,
Martin

Question What if I desire to create the properties dynamically Pin

harsh_godha eighteen-Oct-10 8:07

Member harsh_godha 18-October-10 8:07
Hi Every bit I understand from this code is that, this code calls the properties which are bachelor in the class, I can't create a holding. Correct me if i'yard wrong.
And what if I desire to create properties dynamically.
Question Dynamic properties work fine but what about dynamic Methods and ctors? [modified] Pin

Doomii 5-Aug-08 11:50

Member Doomii 5-Aug-08 11:50
First of all, thanks a lot for this slice of work - It is very helpful in what I am trying to do - Pretty much exactly what i was looking for for a long time! I also extended information technology with a PropertyAccessorMgr class which auto-manages all property accessors that take been created and only creates a new 1 if information technology does not already be.

Now is in that location an easy way to easily invoke methods or ctors dynamically? I'm not sure if this is the right place to ask but I couldn't seem to find whatsoever more info on this matter - And I figured if dynamic property invocation is working, why not methods or ctors? I'm confident someone hither must have the answer Smile | :)

Edit: I realized 2 things that should be mentioned:
ane. The containing class must be public (or -I assume- somehow accessible to the PropertyAccessor).
2. You MUST refer to the bodily form of the object whose holding yous desire to evaluate. You cannot use the PropertyAccessor of an underlying type or interface.

modified on Tuesday, Baronial v, 2008 v:08 PM


General Variant with lambda Pin

Maskaev 9-Apr-08 4:05

Member Maskaev 9-Apr-08 4:05
Quick variation based on lambda functions.

>----------------------------------------
grade LambdaPropertyAccessor<T>
{
private Dictionary<string, Func<T, object>> propAccessors = new Dictionary<string, Func<T, object>>();

public LambdaPropertyAccessor()
{
Type type = typeof (T);

foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.GetProperty
| BindingFlags.Instance))
{
if (!pi.CanRead)
continue;

ParameterExpression parameter = Expression.Parameter(type, "r");

Expression<Func<T, object>> lambda;

if (pi.PropertyType.IsValueType)
{
lambda = Expression.Lambda<Func<T, object>>(
Expression.TypeAs(Expression.Property(parameter, pi.Name), typeof(object)), parameter);
}
else
{
lambda = Expression.Lambda<Func<T, object>>(Expression.Property(parameter, pi.Name), parameter);
}

propAccessors.Add(pi.Name, lambda.Compile());
}
}

public object Become(T obj, cord propName)
{
return propAccessors[propName](obj);
}
}
<----------------------------------------

1000000 property gets on integer...
Direct access ms: 15,625
PropertyAccessor (Reflection.Emit) ms: 78,125
Reflection ms: 4687,5
Lambda ms: 218,75

meg belongings gets on strings...
Direct access ms: xv,625
PropertyAccessor (Reflection.Emit) ms: 46,875
Reflection ms: 4765,625
Lambda ms: 203,125

General Re: Variant with lambda Pin

Anastasiosyal 22-Oct-08 3:54

Member Anastasiosyal 22-October-08 3:54

This is pretty absurd. How would you get most implementing a holding setter with a lamda?
General Re: Variant with lambda Pin

Maskaev 22-Oct-08 4:37

Member Maskaev 22-October-08 4:37

Belongings setter implementation will be a "statement lambda".
I'm not sure that it can be implemented using System.Linq.Expressions.
General Re: Variant with lambda Pin

Member 458154 22-Jan-10 eleven:59

Member Member 458154 22-Jan-x xi:59

Y'all can create dynamic setters.

Add the following lawmaking to the loop in the constructor:

<br />         ParameterExpression paramExpT = Expression.Parameter(typeof(T),                                      "                                      instance");<br />         ParameterExpression paramExpObj = Expression.Parameter(typeof(object),                                      "                                      obj");<br />         Action<T, object> setterLambda =<br />           Expression.Lambda<Activeness<T, object>>(<br />           Expression.Call(paramExpT, pi.GetSetMethod(),<br />           Expression.ConvertChecked(paramExpObj, pi.PropertyType)), paramExpT, paramExpObj)<br />           .Compile();<br />         propSetters.Add(pi.Name, setterLambda);<br />

where propSetters is a member variable:
<br />                                      private                                      Dictionary<cord, Action<T, object>> propSetters =                                      new                                      Dictionary<string, Action<T, object>>();<br />

You tin can then use a Set method to set the value of a property dynamically:
<br />                                      public                                      void                                      Gear up(T obj,                                      string                                      propName,                                      object                                      value)<br />     {<br />       propSetters[propName](obj,                                      value);<br />     }<br />

General pagefile grows boundlessly Pin

bobman77 19-Sep-07 17:35

Member bobman77 19-Sep-07 17:35
I am creating new PropertyAccessor objects in a loop at the charge per unit of about 100 per minute or and then. My pagefile grows at a pretty brisk pace until it overwhelms my calculator. This is in conjunction with table adapters for a data processing application. when I comment out (Property Adapter) pa.Set(...) in all 18 places, this no longer happens. I approximate its the assemblies are being cached at that place. How do I remove them?
General Re: pagefile grows boundlessly Pin

James Nies 22-Sep-07 22:33

Member James Nies 22-Sep-07 22:33

If y'all're non already doing and then, I would recommend caching PropertyAccessors so that you never create more than 1 instance for a given property of a Type. Actually, without doing this, the PropertyAccessor class would exist slower than reflection. If caching the PropertyAccessor is not feasible for your particular application, you tin unload the cached property assemblies by creating the PropertyAccessors and performing your operations within a new AppDomain. When washed with the processing, you tin can then unload that app domain and the assemblies created under it. Still, this introduces code complexity and you'd have to utilize Remoting to communicate across the AppDomain boundaries.
General ModuleBuilder's DefineType throws exception occasionally Pin

Mandeep Singh Bhatia v-Jun-07 0:12

Member Mandeep Singh Bhatia five-Jun-07 0:12
Hullo,
I have been using this code snippet & it worked perfect in .cyberspace 1.0 & 1.one. But ever since I ported to 2.0 there is a strange problem:
AssemblyBuilder newAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);<br /> ModuleBuilder newModule = newAssembly.DefineDynamicModule("                                      Module");<br />                                      TypeBuilder myType = newModule.DefineType("                                        Holding", TypeAttributes.Public);                                    

It throws exception in DefineType .
Say this lawmaking is executed 200 time. It will run fine 199 times but one time it volition throw exception. Only it will surely throw exception everytime I run.
And it throws exception only when I debug using VS2005 non when I direct run.

Does anyone have any clue to this problem.

thanks,
Mandeep.

General Quick Port to Generics Pin

Tobias Hertkorn 30-May-06 sixteen:xx

Member Tobias Hertkorn 30-May-06 sixteen:20
Hullo at that place!

First of all - wow, James, that'southward fantabulous work! I have never used Emit before - and hither it really makes so much sense!

I am using VS 2005 - so I thought, I could do a quick port to .Internet 2.0, merely to learn something virtually Emit. Turns out, information technology is tragically easy to implement it using generics. That is, implementing it using your great lawmaking. Seriously, information technology boils down to removing the casting stuff in your code.

Simply those easy modification give you an additional speed boost and actually cuts the become and set on value types in one-half! And in that location is even so a meaning speed gain on regular objects too.

Have fun downloading GenericPropertyAccessor from my blog, plus an updated examination app.

For those too lazy to click on the link in my blog - here is the direct link:
GenericPropertyAccessor as Zero

Have fun,
Tobi

P.S.: I have no idea, what to put in the header of these files?! How exercise I "conspicuously marking" that I inverse the code but hugely depended on James' piece of work? Is what I did ok, or should I change the header? Aid!

---
Tobi + C# = T#

Question Re: Quick Port to Generics Pin

Leela Krishna 21-Jan-07 0:34

Member Leela Krishna 21-January-07 0:34

First, I thank James very much for the cracking piece of work!

Howdy Tobi, the Generic implemation is very squeamish.
I couldn't pass the property types dynamically to the GenericPropertyAccessor.
Eg:
The below code works fine for cord type property.

GenericPropertyAccessor<propertyaccessortestobject, string=""> propertyAccessor =
new GenericPropertyAccessor<propertyaccessortestobject, <big="">string>("String");

but, I am using the above lawmaking in the iteration of a collection to display all the property values, then I should laissez passer the property type (higleted) dynamically. any help?

LK.

General Re: Quick Port to Generics Pin

Tobias Hertkorn 13-Apr-07 11:52

Member Tobias Hertkorn 13-Apr-07 xi:52

Hey Leela,

I guess for your kind of situation you would take to use James' original PropertyAccessor. But actually I am not too sure if I sympathize the situation y'all are trying to solve.

Sorry. Smile | :)
Tobi

---
Tobi + C# = T#


General Problem with Value Types Pin

Wasp.NET 11-May-06 23:26

Member Wasp.NET xi-May-06 23:26
Hi,
swell work, I've been using it and information technology works fine, but I have a problem: did you ever try accessing properties from a value blazon? If you lot try, for case, to get the property "Width" from a System.Cartoon.Size, you lot don't get the value, merely a "strange" number that seems to be a memory address... I'g totally ignorant about Emit and I'1000 not able to see where the trouble is, did you lot verify the same problems and, if you did, practise you take some hints about it?
Cheers, cheerio, Smile | :)

Wasp

Question Modify to getting all properties Pin

Savas Cilve 6-Jan-06 4:21

Member Savas Cilve 6-Jan-06 4:21
Hi, this lawmaking will be actually helpful to me but i also demand getting name and value of all public properties. and i as well don't have enough noesis almost IL coding. i'll give Blazon and BindingFlags equally parameters instead of holding proper name, and it will give me property info collection.
thanks for your help..

-- savas --

Answer Re: Alter to getting all properties Pin

User 203181 16-May-06 7:27

Member User 203181 16-May-06 seven:27

Given the code equally is and the reflection API (you lot already know about BindingFlags) this should be a like shooting fish in a barrel. Unless you need help coding arrays/collections...?
General Phone call method Pin

NetTry 9-November-05 4:18

Member NetTry 9-Nov-05 4:18
How to brand better (example of reflection) this situation on C#

// assembly1
form c1
{
public void method1()
{}

public int method2()
{
return 100;
}
}

// assembly2
class c2
{
c1 _c1 = new c1();
c3 _c3 = new _c3(_c1);
}

// assembly3
form c3(object _o)
{
_o.method1();
int y = 100;
y = y + _o.method2(); // 200
MessageBox.Evidence(y.ToString()); // 200
}

Question Setting zilch values gives an Exception Pin

Patrick Heymans 2-November-05 22:35

Member Patrick Heymans 2-November-05 22:35
This is nice stuff, but I take one trouble. When I try to set a null value I get a NullReferenceException when the type of the belongings is a ValueType. Is in that location a way to change the generated IL for the SetValue method so that it perfoms a null-check get-go and if and so, set the value to the initial value of a ValueType (for case, 0 for ints)? I tried fixing it myself but the IL language is very difficult.

Cheers.

Pat

Answer Re: Setting null values gives an Exception Pin

James Nies vi-Nov-05 12:23

Member James Nies 6-Nov-05 12:23

Rather than put this logic in the IL of the emitted property accessor, y'all could place it in the Set method of the physical PropertyAccessor (see code beneath). It might fifty-fifty make sense to make the PropertyAccessor a base class with a protected abstract DefaultValue belongings. You could create a concrete implementation for each value type, merely then y'all would also need a manufactory to create the appropriate belongings accessor...
                                      public                                      void                                      Set up(object                                      target,                                      object                                      value) {                                      if(mCanWrite)     {                                      if(this.mEmittedPropertyAccessor ==                                      null)         {                                      this.Init();         }                                                                                    object                                      newValue =                                      value;                                      if(newValue ==                                      null                                      && PropertyType.IsValueType)         {             newValue = DefaultValue;           }                                                                  this.mEmittedPropertyAccessor.Set(target, newValue);     }                                      else                                      {                                      throw                                      new                                      PropertyAccessorException(string.Format("                                      Property \"{0}\" does"                                      +                                      "                                                                              non have a prepare method.", mProperty));     } }

James

General Extended for field accessors Pin

User 203181 22-Jul-05 5:54

Member User 203181 22-Jul-05 5:54
James,

nice work. Information technology was *almost* what i needed. I had the aforementioned use-case regarding public fields instead of backdrop. So I sat down and refactored a flake Smile | :) thank you, it refactored just fine (which compliments your style).

I factored out an (abstract) base course MemberAccessor, which has 2 descendants, FieldAccessor and PropertyAccessor, obviously.

The descendants sole task is to implement EmitSetter() and EmitGetter() (which are abstract methods on the baseclass.

I even saturday downward and refactored the tests. All tests relevant to both fields and methods have moved into a baseclass MemberAccessorTest, and the derived TestFixtures PropertyAccessorTest/FieldAccesorTest extend this with specific tests (e.g. there is no such matter as a WriteOnly field, and no such thing every bit a 'const' property).

Obviously at that place has been major discover/replace Property->Member to keep the naming consistent with the purposes (e.chiliad. IMemberAccessor instead of IPropertyAccessor).

The icing on the cake may be a manufacturing plant method MemberAccessor.Make(...) which will instantiate either a PropertyAccessor or FieldAccessor by reflection.

If you are interested i volition send/upload (?) the extended project 'FastDynamicMemberAccessor.proj'.

PS1. performance might have gone up by a chance to EmitAssembly that creates a 'sealed' class (gives compiler a huge optimization clue)
PS2. yeah I apply public fields for simple XmlSerializer-able classes Smile | :)
PS3. Needless to say, SampleApp runs without modification
PS4. The sharing of 36 test cases across the field/belongings variants has been achieved by implementing PropertyAccessorTestObject/FieldAccessorTestObject with a shared interface IMemberAccessorTestObject Smile | :) that interface is *merely* used for test asserts, not for member access, of course

General Re: Extended for field accessors Pin

Marc Brooks 15-May-06 nine:24

Member Marc Brooks 15-May-06 9:24
General Re: Extended for field accessors Pin

User 203181 16-May-06 6:37

Member User 203181 16-May-06 half dozen:37

billiotlize1951.blogspot.com

Source: https://www.codeproject.com/Articles/9927/Fast-Dynamic-Property-Access-with-C

0 Response to "Dynamically Reading a Class Property in C#"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel