After thinking about it, I posted the field, but to be honest, I cannot decide which one is the best solution (the reason is as follows ).
Code Public class user
{
Internal string _ username;
Public String username {get {return this. _ username;} set {This. _ username = value ;}}
Internal Int? _ Id;
Public Int? Id {get {return this. _ id;} set {This. _ id = value ;}}
}
That is to say, the field must be an internal attribute. Region ~~
Code
Public class fieldproperty <t>
{
Public Delegate void setvaluedelegatehandler (T owner, object value );
Private readonly type parametertype = typeof (object );
Private T _ owner;
Public t owner {get {return this. _ owner ;}}
Private type _ ownertype;
Public fieldproperty (T owner)
{
This. _ owner = owner;
This. _ ownertype = typeof (t );
}
Private dictionary <int, setvaluedelegatehandler> _ cache = new dictionary <int, setvaluedelegatehandler> ();
Public void setpropertyvalue (string propertyname, object value)
{
Setvaluedelegatehandler Sv;
Int hashcode = propertyname. gethashcode ();
If (this. _ cache. containskey (hashcode ))
{
SV = This. _ cache [hashcode];
}
Else
{
String fieldname = "_" + propertyname;
VaR filedinfo = This. _ ownertype. getfield (fieldname, bindingflags. instance | bindingflags. ignorecase | bindingflags. Public | bindingflags. nonpublic );
// Create a dynamic function
Dynamicmethod method = new dynamicmethod ("emitcallable", null, new type [] {This. _ ownertype, parametertype}, this. _ ownertype. Module );
// Obtain the Il generator of the Dynamic Function
VaR IL = method. getilgenerator ();
// Create a local variable, mainly used for object type to propety type
VaR local = Il. declarelocal (filedinfo. fieldtype, true );
// Load the value of the 2nd parameter (T owner, object value)
Il. emit (Opcodes. ldarg_1 );
If (filedinfo. fieldtype. isvaluetype)
{
Il. emit (Opcodes. unbox_any, filedinfo. fieldtype); // if it is a value type, unpack string = (string) object;
}
Else
{
Il. emit (Opcodes. castclass, filedinfo. fieldtype); // if it is a reference type, convert class = object as Class
}
Il. emit (Opcodes. stloc, local); // unpack or convert the above and assign a value to the local variable. Now this local variable is a field of the same data type as the target function.
Il. emit (Opcodes. ldarg_0); // load the first parameter owner
Il. emit (Opcodes. ldloc, local); // load Local Parameters
Il. emit (Opcodes. stdes, filedinfo); // call the field and assign the new value to the old value
Il. emit (Opcodes. Ret); // return
/* The generated dynamic functions are similar:
* Void emitcallable (T owner, object value)
*{
* T local = (t) value;
* Owner. Field = local;
*}
*/
SV = method. createdelegate (typeof (setvaluedelegatehandler) as setvaluedelegatehandler;
This. _ cache. Add (hashcode, SV );
}
SV (this. _ owner, value );
}
}