Avatar billede keepy Seniormester
23. november 2020 - 14:15 Der er 8 kommentarer og
1 løsning

Generic type i strategy pattern

Hej
Jeg har i nedenstående kode forsøgt at retuner en klasse med en generic type (metoden GetPostProfile()), men det virker bare ikke og jeg er ikke helt sikker på hvorfor. Håber i kan hjælpe.

public class Post<T>
    {
        public PostNummer(string PostNummer, T data)
        {
            IPostProfile<T> Strategy = GetPostProfile(PostNummer);
            Strategy.PostNummer = PostNummer;
        }
        public IPostProfile<T> GetPostProfile(string PostNummer)
        {
            switch(PostNummer)
            {
                case "8000":
                    return new <T>PostProfile.NewPostRoute();
                case "8260":
                    return null;
                case "8660":
                    return null;
            }
            return null;
        }
    }
Avatar billede arne_v Ekspert
23. november 2020 - 14:31 #1
Kan du uddybe "virker ikke"?
Avatar billede arne_v Ekspert
23. november 2020 - 14:32 #2
public class Post<T>
    {
        public PostNummer(string PostNummer, T data)

ser forkert ud. Hvis det er en constructir skal det hedde det samme som klassen. Hvis det ikke er en constructor skal der en return type evt. void paa.
Avatar billede keepy Seniormester
23. november 2020 - 21:43 #3
ja det er rigtig constructoren hedder Post.
JEg får en fejl for denne linje return new <T>PostProfile.NewPostRoute();
at den ikke passer til den retunerede type.
Avatar billede arne_v Ekspert
23. november 2020 - 22:20 #4
return new <T>PostProfile.NewPostRoute();

virker ogsaa mystisk.

() antyder et metode kald som returnerer noget, men new antyder at der kommer en type angivelse bagefter.
Avatar billede keepy Seniormester
23. november 2020 - 23:03 #5
JEg prøver lige med hele koden og  fejlen i linje return new NewPostRoute();

Severity    Code    Description    Project    File    Line    Suppression State
Error    CS0266    Cannot implicitly convert type 'WpfApp2.NewPostRoute' to 'WpfApp2.IPostProfile<T>'. An explicit conversion exists (are you missing a cast?)    WpfApp2    C:\Users\Bruger\source\repos\WpfApp2\WpfApp2\Class1.cs    21    Active

namespace WpfApp2
{
    public interface IPostProfile<T>
    {
        string PostNummer;
    }
    public class NewPostRoute : IPostProfile<Class2>
    {

    }
}
namespace WpfApp2
{
    public class Post<T>
    {
        public Post(string PostNummer, T data)
        {
            IPostProfile<T> Strategy = GetPostProfile(PostNummer);
            Strategy.PostNummer = PostNummer;
        }
        public IPostProfile<T> GetPostProfile(string PostNummer)
        {
            switch (PostNummer)
            {
                case "8000":
                    return new NewPostRoute();
                case "8260":
                    return null;
                case "8660":
                    return null;
            }
            return null;
        }
    }
}
namespace WpfApp2
{
    public class Class2
    {
    }
}
Avatar billede arne_v Ekspert
24. november 2020 - 00:51 #6
case "8000":
                    return (IPostProfile<T>) new NewPostRoute();

compiler, men det er virkeligt daarligt design.
Avatar billede arne_v Ekspert
24. november 2020 - 01:13 #7
En generisk klasse som vil smide en class cast exception for alle typer af T som ikke er Class2 er ikke godt.
Avatar billede keepy Seniormester
24. november 2020 - 07:06 #8
Hej Arne
Tak for hjælpen. HAr du et bud på hvordan man burde lave det ? jeg vil gøre brug af forskellige data modeller i interfaces, så jeg ikke skal lave 20 forskellige interfaces hvor modellen for input til en metode er forskellig. Så vil jeg endvidere gerne benytte strategy pattern til at anvende forskellige strategier ved forskellige postnumre.
Avatar billede arne_v Ekspert
24. november 2020 - 14:46 #9
Der vil vaere et problem lige saa lanege at der er en afhaengighed mellem postnummer argumentet og den generiske type T. Og det vil oedelaegge dit design.

Jeg tro at loesningen er at flytte PostProfile creation ud af Post klassen.

Noget a la:


using System;

namespace E
{
    public interface IPostProfile<T>
    {
        void Process(T data);
    }
    public class Class1
    {
    }
    public class PostRoute1 : IPostProfile<Class1>
    {
        public void Process(Class1 data)
        {
        }
    }
    public class Class2
    {
    }
    public class PostRoute2 : IPostProfile<Class2>
    {
        public void Process(Class2 data)
        {
        }
    }
    public class Post<T>
    {
        public Post(IPostProfile<T> strategy, T data)
        {
            strategy.Process(data);
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            new Post<Class1>(new PostRoute1(), new Class1());
            new Post<Class2>(new PostRoute2(), new Class2());
        }
    }
}
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

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