2010-08-11 4 views
5

Ich habe diesen Code:Was ist das C# -Muster, um eine Aktion für eine Reihe von Werten auszuführen?

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); 

... 

und ich möchte den Code Refactoring den Schlüssel/Funktionsdefinition von den Aktionen zu trennen. Key.xxx und Function.xxx sind nicht vom selben Typ.

zB: in Python, habe ich einfach etwas tun könnte, wie:

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) 

Was ist "der richtige Weg" in C# zu tun?

+0

@Jimmy: Ich mag, wie Sie davon ausgehen, dass er davon ausgeht. Vielleicht ist er neu? In jedem Fall wird "for" in C# nicht tun, was er verlangt.Er muss 'foreach' verwenden. –

+0

Ich wünschte, wir könnten Kommentare ablehnen, weil @Jimmy Hoffa hier nicht benötigt wird. – JonH

+0

@Jimmy: Ich bin mir der foreach bewusst, aber ich suchte nach einer nicht-verbose Art, das anfängliche Array zu erstellen. Und ja, ich bin ein C# -Newbie (Entschuldigung) – PabloG

Antwort

13

Sie etwas tun kann, sehr ähnlich:

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); 
    } 
} 

Sie auch LINQ verwenden könnte, wenn man wollte:

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

nun eine Dictionary mit etwas seltsam hier gegeben, dass wir nicht auf der Suche irgendwas. Wenn Sie .NET 4 verwenden, können Sie statt dessen eine Liste mit Tupeln verwenden:

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

und passen Sie die Schleife entsprechend an. Sie könnten einen anonymen Typ, verwenden:

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

Sie sind alle im Grunde als Arten der Darstellung Schlüssel/Funktionspaare handeln :)

+1

Beachten Sie ein mögliches Problem mit der 'Dictionary'-Implementierung: Die Reihenfolge der Paare ** out ** ist nicht garantiert, die gleiche wie die Reihenfolge der Paare ** im**. Wenn diese Reihenfolge wichtig ist, kann dies ein Problem sein. Angesichts der aktuellen Implementierung (in .NET, nicht sicher über Mono) glaube ich, dass * die Paare in der Reihenfolge zurückgibt, in der sie hinzugefügt wurden, da keine entfernt wird. –

+0

danke, der anonyme Typ funktioniert gut! Die anderen Alternativen sind nicht verfügbar: Ich benutze .NET CF 2, leider habe ich es vorher nicht erwähnt. – PabloG

+0

@P Daddy: Ich denke du hast in jeder Hinsicht Recht - und es sollte definitiv nicht darauf ankommen. –

0

Sie könnten einen Dictionary für diese.

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

Key und Funktion Unter der Annahme, sind Aufzählungen, könnten Sie auch versuchen:

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); 
    } 
} 

Alternativ kann, da es beide sieht aus wie Key und Function Aufzählungen sind, und Sie verwenden die gleiche Function enum Wert Name für jeden Key enum Wert, können Sie etwas tun, das ist etwas hübscher, wenn ein bisschen langsamer:

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); 
} 

Okay, vielleicht ist es nicht hübscher. Meh.

Aber, wenn die Werte von Key sind auch die gleichen wie die Werte von Function (das heißt, wenn (int)Key.Orange == (int)Function.Orange, etc.), dann können Sie so etwas wie:

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); 
} 

Nichts davon ist ein direkte Äquivalent des Python-Code, die eher wie dieses wäre:

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); 
} 

das ist das am ausführlichsten Sol alle, aber es ist am flexibelsten.

Verwandte Themen