2

I'd like to create a simple class property which can contain multiple values set from the outside. (Values are of the same type.) Example of property name and contained items:

KnownHidScanners

"\\?\ACPI#IDEA0100#4&b74a345&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}"
"\\?\HID#VID_045E&PID_071D&MI_00#9&e6a1767&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}"

Is there a standard approach in .NET for data type of such a multi-value class property?

When searching MSDN for multi-value property, I can find Properties with Multiple Values concept article which suggests PropertyValueCollection data type. But if you check the data type closer, it is too tightly related to ActiveDirectory.

Off hand I can implement property as

  • array of type
  • collection of type
  • list of type

but which one is the most used approach in out-of-the-box objects when they need multiple-value properties? I'm not long enough with .NET ecosystem to observe what is generally used.

Note: this is not an opinion-based question. I'm asking developers who are long enough with the framework which approach is already used so I can get consistent with standards.

Edit: clarity was improved after first answerer wrote he misread the question

  • Are you sure you need them set from the outside? Current best practices is to favor immutability where possible. – Telastyn Oct 29 '14 at 16:31
  • Okay, good point. So what data type is used in .net as de-facto standard to initalize immutable multi-value lists? (we have nearly the same question). Maybe in the above example the object is application-wide singleton so it needs possility of adjusting the property on-the-fly. But if you decide posting an answer, I will award it if you explain valid .NET standards. Feel free to describe both singleton and non-singleton standards for multi-value property. – miroxlav Oct 29 '14 at 16:39
  • I cannot encourage you strongly enough to not make this a singleton. – Telastyn Oct 29 '14 at 16:45
  • @Telastyn - Special class from the example registers system hooks via unmanaged code, needs to properly dispose them on app exit etc. So I think it must be a singleton. But we can let it serve its purpose and focus on those multi-value properties... – miroxlav Oct 29 '14 at 16:59
5

For a property that with string values like that, I would have:

List<string> KnownHidScanners = new List<string>();

However, if you're going to expose this property externally as an API, there is:

ICollection<string> KnownHidScanners = new List<string>();

or more appropriately is to create your own type that inherits from ICollection like:

public class ScannerCollection : ICollection<string>
{
    //Class definition and implementation of ICollection<T>.
}

See ICollection(T) Interface documentation.

If you are exposing the property externally, but you don't want the user to be able to modify the collection, you should then use the ReadOnlyCollection(T) class like:

ReadOnlyCollection<string> KnownHidScanners = new ReadOnlyCollection<string>(myPrivateListOfScanners);
  • Thank you. Finally I'll definitely use something from System.Collections.Generic, that array named in the question is only a marginal case (like in case of String.Chars() property). I think custom container can make sense in some cases, especially if I wanted to add functionality to items (as per example used in question: GetGuid(item)), or as you write, if the code has to be very expressive. – miroxlav Oct 31 '14 at 10:01
  • I think I actually misread your question. Rather than having a container with a name, you just want to make a property named KnownHidScanners that stores the values you expressed. In this case, I would go with List<string> unless, as you pointed out in your answer, you're exposing it to an API in which case Collection<string> or ReadOnlyCollection<string> would be more appropriate depending on whether or not you want to allow the API user to modify the collection or not. – Aaron Hawkins Oct 31 '14 at 13:28
  • Ok, now it is more clear why the original answer was a bit 'strange' :) I still cannot mark that answer, it will be misleading for other users. If you wish, you can add one more answer based on your recent comment, it might be a good candidate. But the funny point is: why the original answer to misread question got those upvotes :) – miroxlav Oct 31 '14 at 15:05
  • I will just fix the answer. – Aaron Hawkins Oct 31 '14 at 15:36
3

With modern .NET / C# we try to use generics. Check out System.Collections.Generic namespace

I recommend List<T> until you find something it doesn't do for you.

If you need random access of more than 3 values, go with a Dictionary<K,T>

For a small number of values where you always know where they are, you can use Tuples (such as a 3D coordinate, or a complex key, if there wasn't another data structure to use)

  • Yesterday I've made a short study in Object inspector how properties containing word "Items" are declared in the framework. To my surprise, I found every form: array, collection, list and custom types. Based on this answer I'll probably decide for generic collection property if class will be likely exposed through API and for generic List if class is more of internal character. This appears most close what can be observed as a standard in .NET. – miroxlav Oct 31 '14 at 9:41
2

Okay, in the meantime I've invested additional time and made my own study on the topic.

Findings:

  • checking through Object inspector how properties containing word "Items" are declared in existing libraries reveals somewhat a surprise – I found every form: array, collection, list and custom types

  • dominant types are these two: collections (generic or inherited) and lists (mostly generic)

  • answers in this question shed light when to prefer collection and when list. The key is in character of the class: collections are recommended for exposed classes (API etc.), lists are more preferred for internal implementation stuff

    • here must be noted that Collection<T> is no longer part of System.Collections.Generic since .NET .3.5., it's been moved to System.Collections.ObjectModel
  • if property will have some obvious benefit from some specific type, then ignore the above recommendation and use that type. Example is out-of-the-box String.Chars which is an array.

  • defining custom multi-value container type (with item list based on some of the above) has its place if I want to add some custom properties/methods to items or for manipulation with the list etc.

  • some Property design guidelines are also available from the Microsoft, but for this topic they are not very helpful

  • Thanks for returning and sharing the results of your research. – Eric King Oct 31 '14 at 15:17
  • Despite I wanted to mark someone else's answer, after all, as the most helpful answer I'm accepting answer I created after my own research on the topic, because IMHO it most completely answers the question. This answer shares an opinion (but the question was not about opinion) and the other omits Collection, one of most important types for multi-value property. I still appreciate your effors guys and upvote you. – miroxlav Nov 1 '14 at 19:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.