[ wex-alpha @ 01.12.2011. 14:55 ] @
Da li je moguce refleksijom pozvati mutator?

Imam klasu:
Code:

        public string Name { get; set; }
        public DateTime DateCreated {get; set;}


Implementirana klasa:
Code:

public class FirstImpl : Plugin.Plugin, IPlugin
    {
        public FirstImpl()
        {
            Name = "First Implementation";
            DateCreated = DateTime.Now;
        }

        void IPlugin.Print()
        {
            Console.WriteLine("Plugin name is: " + Name + " This Plugin was created on: " + DateCreated);
        }
    }


Refleksija:
Code:

            Assembly a = Assembly.LoadFile(DestinationLocation);
            Type type = a.GetType("FirstPlugin.FirstImpl");
            MethodInfo methodInfo = type.GetMethod("get_Name"); //Interni metod za getter

            object result = null;

            object classInstance = Activator.CreateInstance(type, null);

            result = methodInfo.Invoke(classInstance, null);


Ne radi. Metod se ne izvrsava.

Ako preradim osnovnu klasu, tj. dodam "rucni metod" za izvlacenje imena:
Code:


 public string DajMiIme() // potrebno za refleksiju
        {
            return Name;
        }


Onda kada refleksijom pozovem metod DajMiIme, radi.

Mislim i ovo rijesenje je ok, ali ako vec imam get;set zasto nesto dodavati?

[ Shadowed @ 01.12.2011. 15:11 ] @
Ne znam sada na brzinu odgovor ali svakako mozes refleksijom procitati property pa ti nije ni neophodno da pozivas taj ugradjeni get metod.
[ Shadowed @ 01.12.2011. 15:12 ] @
S druge strane, ako vec imas interface, castuj i pozivaj property na normalan nacin. Tome (bi trebalo da) i sluzi :)
[ mmix @ 01.12.2011. 15:14 ] @
Ne mozes pretpostavljati ime mutatora/accessora, moras ici kao za regularni property

dakle kroz reflekziju izvuces PropertyInfo za Name i onda pozvati njegov GetGetMethod() koji vraca MethodIfno za get accessor.
[ wex-alpha @ 01.12.2011. 15:19 ] @
Citat:
mmix: Ne mozes pretpostavljati ime mutatora/accessora, moras ici kao za regularni property

dakle kroz reflekziju izvuces PropertyInfo za Name i onda pozvati njegov GetGetMethod() koji vraca MethodIfno za get accessor.


Ne pretpostavljam ime mutatora, kada pozovem sve metode iz dll-a, zaista se tako i zove.

[ mmix @ 01.12.2011. 15:44 ] @
Nije isto,

npr sledeci sors:

Code (csharp):

    public class Klasa
    {
        public string Name { get; set; }
        public string ManualNameAccessor() { return Name; }
    }
 


daje sledeci IL:

Code:


.class public auto ansi beforefieldinit Klasa extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: call instance void [mscorlib]System.Object::.ctor()
        L_0006: ret 
    }

    .method public hidebysig instance string ManualNameAccessor() cil managed
    {
        .maxstack 1
        .locals init ([0] string CS$1$0000)
        L_0000: nop 
        L_0001: ldarg.0 
        L_0002: call instance string DemoLib.Klasa::get_Name()
        L_0007: stloc.0 
        L_0008: br.s L_000a
        L_000a: ldloc.0 
        L_000b: ret 
    }


    .property instance string Name
    {
        .get instance string DemoLib.Klasa::get_Name()
        .set instance void DemoLib.Klasa::set_Name(string)
    }

    .method public hidebysig specialname instance string get_Name() cil managed
    {
        .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
        .maxstack 1
        .locals init ([0] string str)
        L_0000: ldarg.0 
        L_0001: ldfld string DemoLib.Klasa::<Name>k__BackingField
        L_0006: stloc.0 
        L_0007: br.s L_0009
        L_0009: ldloc.0 
        L_000a: ret 
    }

    .method public hidebysig specialname instance void set_Name(string 'value') cil managed
    {
        .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: ldarg.1 
        L_0002: stfld string DemoLib.Klasa::<Name>k__BackingField
        L_0007: ret 
    }

    .field private string <Name>k__BackingField
    {
        .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
    }

}


Pogledaj razliku izmedju accessora i manuelne metode:

.method public hidebysig specialname instance string get_Name() cil managed
.method public hidebysig instance string ManualNameAccessor() cil managed

to je indikacija JITu da metod nije standardni i da je upotrebljen negde druge (u definicji propertija), samim tim do njega dolazis tom putanjom.
[ wex-alpha @ 01.12.2011. 20:04 ] @
Vidi vraga sta se krije u IL-u. Na pamet mi nije palo da tamo zarovim :)

Thanks :)

[ Boris B. @ 02.12.2011. 19:35 ] @
U kojoj situaciji moze da ti zatreba get accessor metoda ali ne i property, tj. zasto uopste postoji GetGetMethod? Cisto spekulativno...
[ mmix @ 02.12.2011. 20:34 ] @
zato sto ime Get_PropeortyName nije zagarantovano, sledeca verzija kompajlera ili neki totalno deseti kompajler moze da ga imenuje potpuno drugacije.
[ Boris B. @ 05.12.2011. 08:07 ] @
Ok kapiram to, mislio sam kada moze da ti zatreba GetGetAccessor() umesto obicnog GetValue()?
[ mmix @ 05.12.2011. 09:21 ] @
deferred execution? Metod koji prima MethodInfo parametar pa poziva po potrebi. Nije bas svakodnevna potreba (ni refleksija to nije) ali mozda zatreba.