C#中KeyLogger的问题

时间:2009-06-11 14:59:49

标签: c#

我想记录键盘敲击。但是,当我向keyList添加新键盘时,它会将所有项目更改为新项目。例如,如果keyList包含A和B,并且我键入C,那么我的keyList将是C,C,C而不是A,B,C。

你知道造成这个问题的原因吗?我不应该使用List吗?

KeyboardEvent myKeyBoardEvent = new KeyboardEvent();
List<KeyboardEvent> keyList = new List<KeyboardEvent>();
List<WorkflowEvent> myLogs = new List<WorkflowEvent>();

public void LogKeyboadEvent(Key keyboard)
{
myKeyBoardEvent.Key = keyboard.ToString();
keyList.Add(myKeyBoardEvent);
myLogs.Add(myKeyBoardEvent);
}

2 个答案:

答案 0 :(得分:3)

KeyboardEvent是一个类,因此通过“引用”传递。这意味着您只有一份副本。您将相同的对象添加到列表中3次。

这也会产生同样的效果:

myKeyBoardEvent.Key = "A";
myLogs.Add(myKeyBoardEvent);
myLogs.Add(myKeyBoardEvent);
myLogs.Add(myKeyBoardEvent);
myKeyBoardEvent.Key = "C";

列表现在将包含:C,C,C

要解决此问题,请将myKeyBoardEvent置于函数的本地,并且每次只创建一个新的KeyboardEvent。

这是一个固定版本:

List<KeyboardEvent> keyList = new List<KeyboardEvent>();
List<WorkflowEvent> myLogs = new List<WorkflowEvent>();

public void LogKeyboadEvent(Key keyboard)
{
    KeyboardEvent myKeyBoardEvent = new KeyboardEvent();
    myKeyBoardEvent.Key = keyboard.ToString();
    keyList.Add(myKeyBoardEvent);
    myLogs.Add(myKeyBoardEvent);
}

答案 1 :(得分:0)

这是基本问题。 myKeyBoardEvent是一个引用而不是值,列表包含对同一对象的引用。

正确的实施将是:

public void LogKeyboadEvent(Key keyboard)
{
    keyBoardEvent = new KeyboardEvent();
    keyBoardEvent.Key = keyboard.ToString();
    keyList.Add(keyBoardEvent);
    myLogs.Add(keyBoardEvent);
}

这里它可以工作,但是在myLogs列表上更改对象也会在keyList上更改它。其他方法将占用更多内存,但会保护它免受更改:

public void LogKeyboadEvent(Key keyboard)
{
    keyBoardEvent = new KeyboardEvent();
    keyBoardEvent.Key = keyboard.ToString();
    keyList.Add(keyBoardEvent);
    keyBoardEvent2 = new KeyboardEvent();
    keyBoardEvent2.Key = keyboard.ToString();
    myLogs.Add(keyBoardEvent2);
}

第三种方法是使用List,但这里没有代码交配。