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!
- Est-il une meilleure alternative que de ce "de type"? (5 réponses )
Réponses
Trop de publicités?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
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.
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));
}
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
}