webForumDet fria alternativet

Reflection på webbhotell

.NETur .NET

24 svar · 1 170 visningar · startad av doggelito · sida 2 av 2

Frågan, av doggelito

Att man inte får använda sig av reflection verkar vara "trendigt" bland webbhotell. Läser man på div. hotells specar på vad man får/inte får så kan man lätt tro att de bara kopierat varandras texter. För vissa hotell har exakt samma punktlista! :l Men vad är "farligt" med reflection egentligen eftersom hotellen inte tillåter det?

Läs frågan i sin helhet →
Medlem sedan jan. 20012 204 inlägg
#21

spango skrev:

Njae, vid direkta anrop av metoder etc sker anropen mer i stil med hur de funkar i C++, både i Java och C#, det är därför direkta anrop är så larvigt mycket snabbare än reflection.

Ok, trodde att man inte gjorde det för att komma ifrån "fragile base class problem", eller vad det nu heter.

Medlem sedan maj 20012 812 inlägg
#22

Inspiro skrev:

Däremot har jag svårt att se några direkta tillämpningar. Varför skulle man inte känna till vilka metoder/properties som finns på ett objekt när man skriver sin kod?

Det är för att du inte har byggt en OR-mapper någongång. Det är ett typiskt exempel på när man använder sig av reflection.

Du har en mappningsenhet, som berättar att data från kolumnen: FirstName skall sättas till variablen _FirstName i classen User.

Eftersom du vill att din ORMapper skall vara generisk så kan du inte i din OR Mapper skriva något så här:

User user = new User();
user._FirstName = dataReader["FirstName"].ToString();

Eftersom du så fall skulle få skriva om din ORMapper vid varje nyklass som du vill mappa. Här kommer nu reflections in i bilden. Här kan du skapa en klass utifrån ett namn på klassen, du kan sedan sätta ett värde till en variable med hjälp av reflection.

typ så här:

                       //-- Get field of entity
                        FieldInfo fieldInfo = itemType.GetType().GetField(dataField.ClassFieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

                        //-- Set the value to the entity field
                            fieldInfo.SetValue(itemType, dataReader[dataField.DataFieldName] != DBNull.Value ? dataReader[dataField.DataFieldName] : null);

Jag har ett annat exempel där reflections hjälpte mig, och det var att jag ville komma åt en metod i en klass som var protected och klassen var sealed :) jag kunde alltså inte kalla på den via vanlig kod, men med hjälp av reflections så kunde jag enkelt kalla på denna metod och exekvera det jag ville :)

Dessutom så hjälper reflections mig med att minska antalet kodrader och minska buggar i koden.

Typ så här: Säg att du har en metod som tar emot en enum, denna enum beskriver olika actions som du vill ha utförda. Typ: Save, Load, Clear osv osv..

I denna metod så brukar man då ha en switch-sats och så kanske man från denna switch-sats kallar på olika metoder, Save(), Load(), Clear(). Med reflections så kan du ta bort din switchsats och helt enkelt kallar på respektive metod med hjälp av namet på metoden. Mindre kod helt enkelt... Och inte att förglömma, ett ställe mindre som man måste in och ändra koden i, när man lägger till något i sin enum...

typ så här:

            ProcessCommandMessage processCommandMessage = processCommandEventArgs.ProcessCommandMessage;

            this.GetType().InvokeMember(processCommandMessage.ProcessCommand.ToString()
                , System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod
                , null, this, new object[]{processCommandMessage});

Här är ett exempel på kod som hjälper mig att minimera buggar i min kod.

        internal static void Clear()
        {
            //-- Get all members in the _State object
            FieldInfo[] fields = _State.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic);

            //-- Check if the memeber is of the interface IStateWrapper, if so call the Clear() on that instance or keep looping...
            foreach (FieldInfo fieldinfo in fields)
            {
                object fieldInfoType = fieldinfo.GetValue(_State);
                if (!(fieldInfoType is IStateWrapper))
                    continue;

                ((IStateWrapper)fieldInfoType).Clear();                
            }
        }

Jag har ett Stateobjekt (_State) som innehåller massor med StateWrapper, som innehåller en collection. Om jag lägger till en ny StateWrapper i min State, så vill jag att den också skall tömmas när jag kallar på Clear() metoden på mitt state-objekt. Om jag inte hade haft reflection koden, så hade jag varit tvungen att även lägga till en kodrad i min clear-metod som hade anropa StateWrapperns Clear-metod. Det slipper jag nu eftersom varje gång som jag anropar State.Clear() så kommer den automatisk ta fram alla StateWrapper som jag har och anropa deras Clear() metod. Interface har jag bara för att slippa anropa statewrapperns Clear() med hjälp av reflections, men det hade gått bra det med...

Så det finns massor med tillämpningar för man använder sig av reflections och i några fall så kan man inte lösa problemet utan reflections.

- M

Medlem sedan sep. 2005673 inlägg
#23

Tack för mycket bra svar! Men om nu en ormapper använder reflections, betyder det också att det blir ganska långsamt att jobba med en sådan?

Medlem sedan maj 20012 812 inlägg
#24

inspiro skrev:

Tack för mycket bra svar! Men om nu en ormapper använder reflections, betyder det också att det blir ganska långsamt att jobba med en sådan?

I relation till vad?

Givetviss blir det långsamare att använd sig av en O/R Mapper jämfört med att mappa värderna själv, eller att binda sin datareader direkt till ASP-Controlen.

Men i relation till hur lång tid ditt databasanrop tar, så är det inte så mycket att fundera över. Man får väga för och nackdelar med en O/R Mapper. Och en av nackdelarna är ju att det kräver mer prestanda med en O/R Mapper än utan en. Frågan är om du någonsin kommer att märka skillnaden, skulle inte tro det.

Däremot så märker du skillnaden i din kod/programmering när du jobbar med din data som objekt jämfört med dataset/datareaders...

- M

Medlem sedan juni 20008 205 inlägg
#25

P skrev:

Ok, trodde att man inte gjorde det för att komma ifrån "fragile base class problem", eller vad det nu heter.

Mja, du har iofs 50% rätt i ditt ursprungliga inlägg :) IL- och bytekod använder mycket riktigt metodnamnet, men när VM:en läser in och jittar kod binder den direkt. Så när exekveringen kommer till själva anropet används inte metodnamnet, men däremot används det i den kompilerade koden.

139 ms totalt · 3 externa anrop · v20260731065814-full.25f56b17
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
137 ms — hämta tråd, inlägg och bilagor (db)