C#, Dictionary<int, Type> ??

0

Czy to możliwe, by utworzyć słownik w taki sposób, aby przechowywał w "value" typ zmiennej ?
Tzn, aby zamiast:
Bomba bombaX = new Bomba1();
Bomba bombaY = new Bomba2();
można było napisać:
Bomba bombaX = new dictionary1;
Bomba bombaY = new dictionary2;

gdzie Bomba, to klasa bazowa, a Bomba1, Bomba2 pochodne.

Niekoniecznie chodzi o taki zapis jak powyżej, tylko raczej o to, jak zrealizować taką funkcjonalność za pomocą słownika?
Lub bez użycie słownika, ale w rozsądny sposób. Tak, by nie trzeba było używać instrukcji warunkowych.

3

Np. tak:

var dict = new Dictionary<int, Type> { { 1, typeof(Bomba1) }, { 2, typeof(Bomba2) } };
var bomba = (Bomba)Activator.CreateInstance(dict[1]);

Możesz też utworzyć Dictionary<int, Func<Bomba>>, w którym wartością będzie funkcja zwracająca nowy obiekt.

4

na upartego mozesz sobie trzymac w slowniku typ i uzywac refleksji, ale po co skoro mozesz to zrobic np w ten sposob:

var bomby = new Dictionary<int, Func<Bomba>> { { 1, () => new Bomba1() }, { 2, () => new Bomba2() } };
var bomba1 = bomby[1]();
var bomba2 = bomby[2]();

lub przy uzyciu tablicy:

var bomby = new Func<Bomba>[] { () => new Bomba0(), () => new Bomba1(), () => new Bomba2() };
var bomba1 = bomby[1]();
var bomba2 = bomby[2]();

a moze po prostu stworz fabryke do tego? (wiem wiem, to nie java ;))

0

Dziękuję.
Z delegatami jeszcze się nie zapoznawałem, ale to rzeczywiście wydaje się być jednym z lepszych rozwiązań w tej sytuacji.

Co rozumiesz poprzez "stworzenie fabryki" ?

0

Twoje klasy mogą implementować interfejs ICloneable a później możesz je sobie klonować.

0
JeloneK napisał(a):

Co rozumiesz poprzez "stworzenie fabryki" ?

Ot, chociażby, opakować w funkcję kod @somekinda:

static Bomba CreateBomba(int typ)
{
    return (Bomba)Activator.CreateInstance(dict[typ]);
}

Tylko co to za magiczne inty? Nie lepiej enum? A jeśli to jakiś parametr liczbowy bomby, to powinien mieć sensowną nazwę.

0

A najlepiej jakbyś korzystał z IoC. Na przykład Autofac ma coś takiego jak Keyed Service, dzięki któremu możesz przyporządkować typy do enumów (lub intów jak bardzo chcesz).

http://docs.autofac.org/en/latest/advanced/keyed-services.html

Dla Ciebie to będzie temat przyszłościowy, ale warto, żebyś do tego kiedyś wrócił

0

Wygląda na to, że niepotrzebnie to wszystko komplikowałem. Bo utworzyłem słownik dla każdej wartości, którą chciałem przypisać.

np:

PiecesValue = new Dictionary<char, int>
            {
                { 'E', 0 },
                { 'P', 1 },
                { 'N', 3 },
                { 'B', 3 },
                { 'R', 5 },
                { 'Q', 9 },
                { 'K', 1000 },
            };
 PiecesImagesWhite = new Dictionary<char, string>
            {
                { 'E', "C:/Users/JeloneK/Desktop/ChessPieces/Empty.png" },
                { 'P', "C:/Users/JeloneK/Desktop/ChessPieces/whitePawn.png" },
                { 'N', "C:/Users/JeloneK/Desktop/ChessPieces/whiteKnight.png" },
                { 'B', "C:/Users/JeloneK/Desktop/ChessPieces/whiteBishop.png" },
                { 'R', "C:/Users/JeloneK/Desktop/ChessPieces/whiteRock.png" },
                { 'Q', "C:/Users/JeloneK/Desktop/ChessPieces/whiteQueen.png" },
                { 'K', "C:/Users/JeloneK/Desktop/ChessPieces/whiteKing.png" },
            };

itd.
A bardziej rozważane wydaje się być utworzenie tablicy typu Object[] dla każdego z typów, i tam zapisanie wszystkich parametrów. Leczy czy poprawnym zachowaniem jest rzutowanie ich potem na odpowiadające im typy ? I w jaki sposób najlepiej to rzutowanie wykonać ?

0

użyj enuma a nie chara.

0

Przechowywanie Object[] do tego jest zdecydowanie złym pomysłem. Użyj klasy lub struktury.

0

a czemu sobie nie stworzysz typu w stylu

public sealed class Piece
{
    public char Symbol { get; private set; }
    public int Value { get; private set; }
    public string ImageWhite { get; private set; }
    public string ImageBlack { get; private set; }

    public Piece(char symbol, int value, string imageWhite, string imageBlack)
    {
        Symbol = symbol;
        Value = value;
        ImageWhite = imageWhite;
        ImageBlack = imageBlack;
    }
}

potem zdefiniuj wszystkie obiekty i operuj nimi w programie zamiast bawic sie w wyciaganie ze slownikow

0

Ostatecznie właśnie tak (podobnie) zrobiłem ^^

Mimo to, mam ogromny problem z dostrzeżeniem tego względnie optymalnego rozwiązania. Jest bardzo wiele sposobów, by zrobić to tak, aby uzyskać zamierzony efekt i bardzo wiele czasu poświęcam na wybranie tego 'właściwego' i drażni mnie to, bo sprawia mi to duży problem.

1

sie tak nie denerwuj, tak wlasnie sie tworzy programy - poprzez ciagle ulepszanie. jak zauwazasz ze robisz sporo copy-paste i/lub rzutowan to znaczy ze zbladziles i szukaj innego sposobu. oczwiscie mozna ulepszac w nieskonczonosc, nawet najlepsi maja problem ze znalezieniem balansu miedzy swietnym kodem a stopniem ukonczenia projektu ;) moze postaraj sie napisac jak najwiecej funkcjonalnosci a potem zmieniaj strukture programu tak zeby kod byl ladniejszy.

0

bardzo wiele czasu poświęcam na wybranie tego 'właściwego'

No patrz a ja do dzisiaj tak mam :P

1 użytkowników online, w tym zalogowanych: 0, gości: 1