Avatar billede intel4004 Novice
22. april 2005 - 15:15 Der er 13 kommentarer og
2 løsninger

Hjælp søges i forbindelse med as operatoren (eller bare typecast)

Mit første spørgsmål i C# kategorien :)

Jeg søger en måde hvorpå jeg kan mappe et klassenavn (lagret som en string) så den kan bruges som typecast typen i as operatoren.

Eksempel:
Object someObject = someFieldAsObject;
string typeStr = someObject.GetType().Name;
SomeProperty = (double)(someObject as MapStringToType(typeStr,ConcreteClassType).SomeProperty);

Jeg håber i forstår? Jeg søger den magiske MapStringToType() metode :) Er nybegynder i C# men har god erfaring med Java.

En alternativ metode - som jeg gerne vil undgå - er at switche på de forskellige typer af typer som mit object kan kastes som. Men denne metode ville være langt mere fleksibel...

Mvh Intel4004
Avatar billede intel4004 Novice
22. april 2005 - 15:17 #1
Rettelse:

SomeProperty = (double)(someObject as MapStringToType(typeStr,ConcreteClassType)).SomeProperty;

Intel4004
Avatar billede arne_v Ekspert
22. april 2005 - 15:18 #2
Du kan ikke caste til noget der bestemmes på runtime.

Ligesom i Java kan du:
  - bruge reflection til at finde det du skal bruge
  - caste til et interface eller abstrakt basis klasse som de alle arver fra
  - switche
Avatar billede nielle Nybegynder
22. april 2005 - 16:32 #3
Hvorfor ønsker du at typecaste? Det lyder som om polymorfi er den rigtige løsning på problemet - altså at bruge virtual funktioner.
Avatar billede nielle Nybegynder
22. april 2005 - 16:43 #4
using System;

namespace PocEksperten003
{
    class BaseClass
    {
        public virtual double SomeProperty
        {
            get { return 42; }
        }
    }

    class AClass : BaseClass
    {
        public override double SomeProperty
        {
            get { return 43; }
        }

    }

    class BClass : BaseClass
    {
        public override double SomeProperty
        {
            get { return 44; }
        }

    }

    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            BaseClass BC;
           
            BC = new BaseClass();
            Console.WriteLine(BC.SomeProperty);

            BC = new AClass();
            Console.WriteLine(BC.SomeProperty);

            BC = new BClass();
            Console.WriteLine(BC.SomeProperty);
        }
    }
}
Avatar billede nielle Nybegynder
22. april 2005 - 16:46 #5
Variablen BC er af typen BaseClass og kan indeholde en instans af klasserne BaseClass, AClass eller BClass. Alt efter hvilken der er tale om, så finder den selv ud af hvilken variant af SomeProperty der skal kaldes.

Output:
42
43
44
Avatar billede intel4004 Novice
22. april 2005 - 23:36 #6
Jeg har gang i at implementere en speciel version af interpreter pattern. Jeg bygger en interpreter som universitets-projekt.

Men jeg havde faktisk overset at jeg kunne bruge den intelligens som nielle snakker om - og arne_v har helt sikkert ret. Det plejer du at have arne_v :)

Men mit problem er løst og jeg deler pointene lige imellem jer...

Mvh Intel4004
Avatar billede intel4004 Novice
22. april 2005 - 23:36 #7
Øhh hvis i begge lige vil smide et svar?
Avatar billede arne_v Ekspert
22. april 2005 - 23:39 #8
ok
Avatar billede nielle Nybegynder
23. april 2005 - 08:23 #9
ok
Avatar billede nielle Nybegynder
23. april 2005 - 09:17 #10
Doh!

Hvis du er nybegynder i C# er reflektion måske en kende langhårdet at gå igang med. Ellers er det et meget stærkt værktøj, men en kende overkill til dit problem.
Avatar billede intel4004 Novice
24. april 2005 - 00:44 #11
nielle>
Jeg er kommet videre i C# siden dette spørgsmål :) Så vidt jeg forstår reflection så giver det muligheden for (blandt andet) at få listet alle mulige oplysninger om en klasse (kalde en bestemt metode udfra en søgning på navnet etc.)

Kunne ikke lige se hvordan jeg kunne bruge det her. Men alt i alt virker det nu. Jeg havde glemt den frihed som polymorfi giver mig. Jeg sparer nu utrolig mange linier kode bare ved at arve og override...den med Java er også lang tid siden :)

Mvh Intel4004
Avatar billede nielle Nybegynder
24. april 2005 - 07:21 #12
using System;
using System.Reflection;

class ClassA
{
    public double SomeProperty { get { return 43; } }
}

class ClassB
{
    public double SomeProperty { get { return 44; } }
}

class Class1
{
    public static void InvokeProperty(object ClassX)
    {
        Type TypeX = ClassX.GetType();
        PropertyInfo SomePropertyX = TypeX.GetProperty("SomeProperty");
        double SomePropertyValue = (double) SomePropertyX.GetValue(ClassX, null);
        Console.WriteLine(SomePropertyValue);
    }

    [STAThread]
    static void Main(string[] args)
    {
        InvokeProperty(new ClassA());

        ClassB B = new ClassB();
        InvokeProperty(B);
    }
}
Avatar billede intel4004 Novice
24. april 2005 - 11:24 #13
nielle>

Ja det er sku smart :) Så man kan altså i runtime definere hvilken property man vil benytte, og i hvilken klasse den skal ligge? Jeg er som sagt stadig ved øve mig i at benytte krafterne bag polymorfi.

Intel4004
Avatar billede nielle Nybegynder
24. april 2005 - 11:59 #14
"Definere" er det forkerte ord i lige denne sammenhæng hvor det mere går ud på at finde en property som du kender navnet på. Men den slags kan man faktisk også gøre.
Avatar billede arne_v Ekspert
24. april 2005 - 12:12 #15
Reflection er lidt besværligt og har også et vist performance overhead.

Men det er nødvendigt hvis du ikke har mulighed for at lade dine klasser
arve fra noget fælles.

(du kan iøvrigt lave tilsvarende i Java)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester