2010-09-18 28 views
6

Tôi đã tạo bảng điều khiển cho trò chơi của mình trong XNA và tôi có đại biểu cho khi lệnh được nhập. Tại thời điểm này, đại biểu trả về giá trị bool. Tôi đã tuyên bố một sự kiện bên trong lớp Console (trả về false) và sau đó đăng ký với sự kiện này từ các lớp khác. Ý tưởng là, nếu không có lớp nào đăng ký sự kiện này trả về true thì người ta cho rằng người dùng đã nhập một lệnh không hợp lệ. Tuy nhiên, nếu ít nhất một trong các lớp được đăng ký trả về true thì lệnh được giả định là hợp lệ.C# "HOẶC" đại biểu sự kiện quay lại bool

Hiện tại, chỉ có một lớp được xem xét trả về đúng hoặc sai, có cách nào tôi có thể xem xét giá trị trả về của tất cả các lớp đăng ký sau đó HOẶC kết quả của chúng không?

Cảm ơn,

+1

Đẹp Q - AFAIK một nhiệm vụ đơn giản sẽ luôn trả về kết quả của người đăng ký cuối cùng. – StuartLC

Trả lời

3

I figured it out cũng giống như tôi đặt ra câu hỏi này: P

bool handled = false; 
foreach (Delegate d in CommandProcessed.GetInvocationList()) 
    handled |= (bool) d.DynamicInvoke (gameTime, command.ToString()); 

if (!handled) { } // Command Unrecognized 

đâu CommandProcessed là sự kiện của tôi rằng các lớp học đăng ký.
Đại biểu của tôi có hai đối số: gametime và chuỗi lệnh.

+0

Đúng - Tôi đã phải giải quyết vấn đề tương tự này gần đây để xác nhận chuỗi. Các bitwise hoặc nhà điều hành không ngắn mạch như boolean hoặc nhà điều hành không. – arootbeer

6

Từ bên trong lớp mà tuyên bố sự kiện này, bạn có thể lấy lại gọi-danh sách các sự kiện (giả định một sự kiện lĩnh vực tương tự). Gọi từng cá nhân riêng lẻ sẽ cho phép bạn kiểm tra giá trị trả lại của từng người đăng ký đối với sự kiện.

Ví dụ:

public event Func<bool> MyEvent = delegate { return false; }; 

...  

private bool EmitMyEventAndReturnIfAnySubscriberReturnsTrue() 
{ 
    return MyEvent.GetInvocationList() 
        .Cast<Func<bool>>() 
        .Select(method => method()) 
        .ToList() //Warning: Has side-effects 
        .Any(ret => ret); 
} 

Trong ví dụ này, mỗi thuê bao được thông báo về sự kiện này - không có ngắn mạch xảy ra nếu ai trong số họ với McNamara. Hành vi này có thể dễ dàng thay đổi nếu muốn bằng cách xóa cuộc gọi đến ToList().

Thành thật mà nói, tôi không thực sự thích các sự kiện trả về giá trị; ngữ nghĩa của họ không rõ ràng với người đăng ký. Tôi sẽ thay đổi thiết kế nếu có thể.

CHỈNH SỬA: Sửa lỗi trong buộc thực hiện đầy đủ chuỗi dựa trên nhận xét của Timwi.

+2

Sẽ không xảy ra với tôi để sử dụng LINQ cho việc này. Câu trả lời hay. –

+0

Tôi nhìn vào hai thiết kế khác nhau và đây là chất tẩy rửa của cả hai. Và nó khá dễ hiểu và thực hiện. Tôi không quen thuộc với LinQ nhưng tôi đã tìm thấy một giải pháp thay thế như tôi mô tả dưới đây. – Dave

+0

@Dave: Giải pháp thay thế bạn đã đăng có cùng ý tưởng với câu trả lời của tôi - mẹo là truy cập danh sách yêu cầu. Tuyệt quá. – Ani

0

Tôi đồng ý với sự cố về các sự kiện trả về các giá trị vì nó dường như cũng xảy ra với tôi. Tuy nhiên một sự thay thế là bạn có thể tạo một lớp mới CommandEventArgs:

class CommandEventArgs : EventArgs 
{ 
    public DateTime GameTime {get; set; } 
    public string Command {get; set;} 
    public bool Valid {get; set;} 
} 

sau đó sử dụng một thể hiện của phương pháp này để gọi sự kiện này và sau đó nếu người nghe nhận lệnh có nó đặt Valid là true. Do đó nếu Valid vẫn sai sau khi gọi, bạn biết lệnh không được công nhận.

Đây là cách .NET xử lý các sự kiện bàn phím mà bạn đặt KeyEventArgs.Handled thành true để ngăn chặn bất kỳ hành động nào khác xảy ra với sự kiện.

Các vấn đề liên quan