Exposing a queue as a public property
-
Is anybody aware of any guidelines, issued by Microsoft or any other parties, about exposing a Queue or Queue<T> as a public property on an object? I recall some old guidelines about exposing a generic collection, but I can't find any recent information about that, either.
-
Is anybody aware of any guidelines, issued by Microsoft or any other parties, about exposing a Queue or Queue<T> as a public property on an object? I recall some old guidelines about exposing a generic collection, but I can't find any recent information about that, either.
Yeah, it's best not to unless you really want other classes to have access. For one thing, it exposes implementation which makes altering the implementation difficult later. Another problem would be if one class is iterating (
foreach
ing) the collection when another is trying to alter it. What are you trying to accomplish? Think in terms of interface. Will AddItem and/or GetItem methods suffice? -
Is anybody aware of any guidelines, issued by Microsoft or any other parties, about exposing a Queue or Queue<T> as a public property on an object? I recall some old guidelines about exposing a generic collection, but I can't find any recent information about that, either.
I have not come across any such guidelines. Its best advised not to use public for any property, unless you really have to.
Build your own survey - http://www.factile.net
-
Is anybody aware of any guidelines, issued by Microsoft or any other parties, about exposing a Queue or Queue<T> as a public property on an object? I recall some old guidelines about exposing a generic collection, but I can't find any recent information about that, either.
Exposing any collection as a public property means that you lose control over the collection, because the calling class can push, pop and inspect items in the collection. It also potentially causes synchronisation issues if you use that collection within your own code and expect it to be unchanging (in particular, if you enumerate over it). I won't say 'don't do it', because it's often extremely convenient to do so, at least with a list where you want to provide access and you don't want to write a bunch of pointless IList wrapper methods to protect it. (With a queue, chances are all you want to allow the caller to do is add to it, so in that case I would write a wrapper method so I could use something other than a queue later.) But if you do expose a collection, make sure you put a note of caution about how a caller should use it in the documentation, and remember that you're relying on the end user being responsible. If you do choose to expose a collection, it's generally better to expose it as the relevant interface instead of the concrete class, since the Framework provides both. That allows you to change your underlying data structure in future, and expose a shim that supports the interface and maps to whatever you now use. None of this has anything to do with generics, by the way. It is exposing collections to the outside that you should be wary of.
-
Exposing any collection as a public property means that you lose control over the collection, because the calling class can push, pop and inspect items in the collection. It also potentially causes synchronisation issues if you use that collection within your own code and expect it to be unchanging (in particular, if you enumerate over it). I won't say 'don't do it', because it's often extremely convenient to do so, at least with a list where you want to provide access and you don't want to write a bunch of pointless IList wrapper methods to protect it. (With a queue, chances are all you want to allow the caller to do is add to it, so in that case I would write a wrapper method so I could use something other than a queue later.) But if you do expose a collection, make sure you put a note of caution about how a caller should use it in the documentation, and remember that you're relying on the end user being responsible. If you do choose to expose a collection, it's generally better to expose it as the relevant interface instead of the concrete class, since the Framework provides both. That allows you to change your underlying data structure in future, and expose a shim that supports the interface and maps to whatever you now use. None of this has anything to do with generics, by the way. It is exposing collections to the outside that you should be wary of.
I'm exposing a recorded history of events (changes to a database), in the order that they occured. I expect to update the queue periodically. Original order of events is important. I expect the user to periodically consume this information, in order, and then come back for more. So I was using a queue as it enables them to dequeue at will, while maintaining the original order, and keeping track of which events they have already noted/processed. The user really only needs to dequeue (ie, remove one item at a time, and be able to tell that they have consumed all the items currently available).
-
I'm exposing a recorded history of events (changes to a database), in the order that they occured. I expect to update the queue periodically. Original order of events is important. I expect the user to periodically consume this information, in order, and then come back for more. So I was using a queue as it enables them to dequeue at will, while maintaining the original order, and keeping track of which events they have already noted/processed. The user really only needs to dequeue (ie, remove one item at a time, and be able to tell that they have consumed all the items currently available).
If the user tries to dequeue as you are trying to enqueue, I think odd things can happen. It may be better to instead expose an event for when a new event should be posted, and have the user catch that event and add the item to a local queue, which it can dequeue when convenient.
-
I'm exposing a recorded history of events (changes to a database), in the order that they occured. I expect to update the queue periodically. Original order of events is important. I expect the user to periodically consume this information, in order, and then come back for more. So I was using a queue as it enables them to dequeue at will, while maintaining the original order, and keeping track of which events they have already noted/processed. The user really only needs to dequeue (ie, remove one item at a time, and be able to tell that they have consumed all the items currently available).
Consider an event for that. Among other things it allows multiple listeners.
-
Consider an event for that. Among other things it allows multiple listeners.
Heh. Actually, this code was written to prevent the user from having to deal with events. I'm wrapping a COM object which does raise events, but has complexities and issues that are problematic. This code maps an event raiser to something a user can poll. If those are the primary concerns, I'll stick with this model for now. My stress tests should tell me how much collision I'm seeing during my internal enqueue. Thanks everybody!
-
Heh. Actually, this code was written to prevent the user from having to deal with events. I'm wrapping a COM object which does raise events, but has complexities and issues that are problematic. This code maps an event raiser to something a user can poll. If those are the primary concerns, I'll stick with this model for now. My stress tests should tell me how much collision I'm seeing during my internal enqueue. Thanks everybody!
Then maybe have Enqueue and Dequeue methods.