261 votes

C# commutateur de type

Double Possible:
C# Est - il une meilleure alternative que de ce "de type"?

C# ne prend pas en charge la commutation sur le type d'un objet. Quel est le meilleur modèle de simulation de ce:

switch (typeof(MyObj))
    case Type1:
    case Type2:
    case Type3:

Merci!

284voto

gjvdkamp Points 3441

C'est un trou dans C#, s'de jeu, pas d'argent bullit encore.

Vous devriez google sur le "modèle visiteur", mais il peut être un peu lourd pour vous, mais encore quelque chose que vous devriez connaître.

Voici une autre de prendre sur la question à l'aide de Linq: http://community.bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch.aspx

Sinon quelque chose le long de ces lignes pourrait aider

// nasty..
switch(MyObj.GetType.ToString()){
  case "Type1": etc
}

// clumsy...
if myObj  is Type1 then
if myObj is Type2 then

etc.

Bonne chance!

GJ

236voto

Mark H Points 9127

J'ai l'habitude d'utiliser un dictionnaire des types et des délégués.

var @switch = new Dictionary<Type, Action> {
    { typeof(Type1), () => ... },
    { typeof(Type2), () => ... },
    { typeof(Type3), () => ... },
};

@switch[typeof(MyType)]();

C'est un peu moins flexable que vous ne pouvez pas tomber à travers les cas, continuer etc. Mais j'ai rarement le faire de toute façon.

29voto

cdiggins Points 5549

Il y a une réponse simple à cette question au Commutateur de cas de type c# qui utilise un dictionnaire de types à la recherche d'une fonction lambda.

Voici comment il pourrait l'être

    var ts = new TypeSwitch()
        .Case((int x) => Console.WriteLine("int"))
        .Case((bool x) => Console.WriteLine("bool"))
        .Case((string x) => Console.WriteLine("string"));

    ts.Switch(42);     
    ts.Switch(false);  
    ts.Switch("hello"); 
}

Il est également généralisée solution à ce problème en termes de filtrage (les deux types d'exécution et vérifié les conditions) au commutateur / pattern matching idée

  var getRentPrice = new PatternMatcher<int>()
        .Case<MotorCycle>(bike => 100 + bike.Cylinders * 10) 
        .Case<Bicycle>(30) 
        .Case<Car>(car => car.EngineType == EngineType.Diesel, car => 220 + car.Doors * 20)
        .Case<Car>(car => car.EngineType == EngineType.Gasoline, car => 200 + car.Doors * 20)
        .Default(0);

    var vehicles = new object[] {
        new Car { EngineType = EngineType.Diesel, Doors = 2 },
        new Car { EngineType = EngineType.Diesel, Doors = 4 },
        new Car { EngineType = EngineType.Gasoline, Doors = 3 },
        new Car { EngineType = EngineType.Gasoline, Doors = 5 },
        new Bicycle(),
        new MotorCycle { Cylinders = 2 },
        new MotorCycle { Cylinders = 3 },
    };

    foreach (var v in vehicles)
    {
        Console.WriteLine("Vehicle of type {0} costs {1} to rent", v.GetType(), getRentPrice.Match(v));
    }

3voto

IAbstract Points 9384

J'ai utilisé cette forme d' switch-case en de rares occasions. Même alors, j'ai trouvé un autre moyen de faire ce que je voulais. Si vous trouvez que c'est la seule façon d'accomplir ce que vous avez besoin, je vous recommande @Mark H de la solution.

Si cela est destiné à être une sorte d'usine de création de processus de prise de décision, il y a de meilleures façons de le faire. Sinon, vraiment, je ne vois pas pourquoi vous voulez utiliser le commutateur sur un type.

Voici un petit exemple de l'expansion de la Marque de la solution. Je pense que c'est un excellent moyen de travailler avec des types:

Dictionary<Type, Action> typeTests;

public ClassCtor()
{
    typeTests = new Dictionary<Type, Action> ();

    typeTests[typeof(int)] = () => DoIntegerStuff();
    typeTests[typeof(string)] = () => DoStringStuff();
    typeTests[typeof(bool)] = () => DoBooleanStuff();
}

private void DoBooleanStuff()
{
   //do stuff
}

private void DoStringStuff()
{
    //do stuff
}

private void DoIntegerStuff()
{
    //do stuff
}

public Action CheckTypeAction(Type TypeToTest)
{
    if (typeTests.Keys.Contains(TypeToTest))
        return typeTests[TypeToTest];

    return null; // or some other Action delegate
}

2voto

Ghyath Serhal Points 3458

Je l'ai fait une fois avec une solution de contournement, j'espère que ça aide.

string fullName = typeof(MyObj).FullName;

switch (fullName)
{
    case "fullName1":
    case "fullName2":
    case "fullName3":
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X