2010-08-11 4 views
5

Je possède ce code:Quel est le motif C# pour effectuer une action sur une série de valeurs?

if (PsionTeklogix.Keyboard.Keyboard.GetModifierKeyState(Key.Orange) == KeyState.Lock) 
    PsionTeklogix.Keyboard.Keyboard.InjectKeyboardCommand(Function.Orange, 0, 0); 

if (PsionTeklogix.Keyboard.Keyboard.GetModifierKeyState(Key.Blue) == KeyState.Lock) 
    PsionTeklogix.Keyboard.Keyboard.InjectKeyboardCommand(Function.Blue, 0, 0); 

if (PsionTeklogix.Keyboard.Keyboard.GetModifierKeyState(Key.Shift) == KeyState.Lock) 
    PsionTeklogix.Keyboard.Keyboard.InjectKeyboardCommand(Function.Shift, 0, 0); 

if (PsionTeklogix.Keyboard.Keyboard.GetModifierKeyState(Key.Control) == KeyState.Lock) 
    PsionTeklogix.Keyboard.Keyboard.InjectKeyboardCommand(Function.Control, 0, 0); 

... 

et je veux factoriser le code séparant la définition clé/fonction des actions. Key.xxx et Function.xxx ne sont pas du même type.

par exemple: en Python, je pourrais simplement faire quelque chose comme:

keys = (
    (Key.Orange, Function.Orange), 
    (Key.Blue , Function.Blue), 
    (Key.Shift , Function.Shift), 
    ... 
    ) 

psi_key = PsionTeklogix.Keyboard.Keyboard 

for key, func in keys: 
    if psi_key.GetModifierKeyState(key) == KeyState.Lock): 
     psi_key.InjectKeyboardCommand(func, 0, 0) 

Ce qui est "le droit chemin" à faire en C#?

+0

@Jimmy: J'aime la façon dont vous présumez qu'il assume. Peut-être qu'il est nouveau? En tout cas, 'for' en C# ne fera pas ce qu'il demande.Il doit utiliser 'foreach'. –

+0

Je souhaite que nous pourrions downvote commentaires parce que @Jimmy Hoffa qui n'est pas nécessaire ici. – JonH

+0

@Jimmy: Je suis au courant de foreach, mais je cherchais un moyen non-verbeux pour construire le tableau initial. Et oui, je suis un débutant C# (désolé à ce sujet) – PabloG

Répondre

13

Vous pouvez faire quelque chose de très similaire:

Dictionary<Key, Function> keys = new Dictionary<Key, Function> 
{ 
    { Key.Orange, Function.Orange }, 
    { Key.Blue, Function.Blue } 
    ... 
}; 

foreach (var pair in keys) 
{ 
    if (Keyboard.GetModifierKeyState(pair.Key) == KeyState.Locked) 
    { 
     Keyboard.InjectKeyboardCommand(pair.Value, 0, 0); 
    } 
} 

Vous pouvez même utiliser LINQ si vous vouliez:

foreach (var pair in keys.Where(pair => 
       Keyboard.GetModifierKeyState(pair.Key) == KeyState.Locked) 
{ 
    Keyboard.InjectKeyboardCommand(pair.Value, 0, 0); 
} 

Maintenant, en utilisant un Dictionary est quelque peu étrange ici étant donné que nous ne cherchons pas quoi que ce soit. Si vous utilisez .NET 4, vous pouvez utiliser une liste de tuples à la place:

var keys = new List<Tuple<Key, Function>>() 
{ 
    Tuple.Of(Key.Orange, Function.Orange), 
    Tuple.Of(Key.Blue, Function.Blue), 
    ... 
}; 

et d'ajuster la boucle en conséquence. Vous pouvez utiliser un type anonyme aussi:

var keys = new[] 
{ 
    new { Key = Key.Orange, Function = Function.Orange }, 
    new { Key = Key.Blue, Function = Function.Blue }, 
    ... 
}; 

Ils agissent tous comme essentiellement façons de représenter clés/paires de fonction :)

+1

Notez un problème potentiel avec l'implémentation de 'Dictionary': L'ordre des paires ** out ** n'est pas garanti d'être le même que l'ordre des paires ** dans**. Si cet ordre est important, cela peut poser problème. Cependant, compte tenu de l'implémentation actuelle (dans .NET, pas sûr de Mono), je crois que cela * va * retourner les paires dans le même ordre qu'elles ont été ajoutées, car aucune n'est jamais supprimée. –

+0

merci, le type anonyme fonctionne bien! Les autres alternatives ne sont pas disponibles: J'utilise .NET CF 2, désolé je ne l'ai pas mentionné auparavant. – PabloG

+0

@P Daddy: Je pense que vous avez raison sur tous les points - et il ne devrait définitivement pas en dépendre. –

0

Vous pouvez utiliser un Dictionary pour cela.

Dictionary<Key, Function> map = new Dictionary<Key, Function>(); 

map.Add(Key.Orange, Function.Orange); 
map.Add(Key.Blue, Function.Blue); 
map.Add(Key.Shift, Function.Shift); 
map.Add(Key.Control, Function.Control); 

foreach(var pair in map) 
{ 
    if (PsionTeklogix.Keyboard.Keyboard.GetModifierKeyState(map.Key) == KeyState.Lock) 
    { 
     PsionTeklogix.Keyboard.Keyboard.InjectKeyboardCommand(map.Value, 0, 0); 
    } 
} 
1

En supposant clés et la fonction sont énumérations, vous pouvez également essayer:

foreach (Key key in Enum.GetValues(typeof(Key))) 
{ 
    if (PsionTeklogix.Keyboard.Keyboard.GetModifierKeyState(key) == KeyState.Lock) 
    { 
     PsionTeklogix.Keyboard.Keyboard.InjectKeyboardCommand((Function)Enum.Parse(typeof(Function), key.ToString()), 0, 0); 
    } 
} 
1
using PsionTeklogix.Keyboard; /* assuming that's a namespace, */ 
           /* otherwise, you can optionally do: */ 
/* using Keyboard = PsionTeklogix.Keyboard.Keyboard; */ 

class Foo{ 
    static readonly Key[] keys = {Key.Orange, Key.Blue, Key.Shift, ...}; 
    static readonly Function[] functions = {Function.Orange, Function.Blue, Function.Shift, ...}; 

    static void Main(){ 
     for(int i = 0; i < keys.Length; i++) 
      if(Keyboard.GetModifierKeyState(keys[i]) == KeyState.Lock) 
       Keyboard.InjectKeyboardCommand(func, 0, 0); 
    } 
} 

Alternativement, car il ressemble à la fois Key et Function sont énumérations, et vous utilisez le même Function enum value name pour chaque Key valeur enum, vous pouvez faire quelque chose comme ceci, ce qui est légèrement plus joli, si un peu plus lent:

static readonly string[] values = {"Orange", "Blue", "Shift", ...}; 

static void Main(){ 
    foreach(string value in values) 
     if(Keyboard.GetModifierKeyState((Key)Enum.Parse(typeof(Key), value)) == KeyState.Lock); 
      Keyboard.InjectKeyboardCommand((Function)Enum.Parse(typeof(Function), value), 0, 0); 
} 

D'accord, peut-être que ce n'est pas plus joli. Meh.

Mais, si les valeurs de Key sont également les mêmes que les valeurs de Function (qui est, si (int)Key.Orange == (int)Function.Orange, etc.), vous pouvez faire quelque chose comme:

static readonly Key[] keys = {Key.Orange, Key.Blue, Key.Shift, ...}; 

static void Main(){ 
    foreach(Key key in keys) 
     if(Keyboard.GetModifierKeyState(key) == KeyState.Lock); 
      Keyboard.InjectKeyboardCommand((Function)key, 0, 0); 
} 

Aucune de ces est une directe équivalent du code Python, ce qui serait plus comme ceci:

class KeyFunction{ 
    readonly Key  key; 
    readonly Function function; 

    public Key  Key  {get{return key;}} 
    public Function Function{get{return function;}} 

    public KeyFunction(Key key, Function function){ 
     this.key  = key; 
     this.function = function; 
    } 
} 

static readonly KeyFunction[] keyFunctions = { 
    new KeyFunction(Key.Orange, Function.Orange), 
    new KeyFunction(Key.Blue, Key.Blue), 
    new KeyFunction(Key.Shift, Key.Shift), 
    ... 
}; 

static void Main(){ 
    foreach(KeyFunction kf in keyFunctions) 
     if(Keyboard.GetModifierKeyState(kf.Key) == KeyState.Lock) 
      Keyboard.InjectKeyboardCommand(kf.Function, 0, 0); 
} 

C'est le sol le plus bavard de tous, mais c'est le plus flexible.

Questions connexes