1

I have a virtual method that returns a collection of items that must be unique. I want to make sure that it will be obvious when overriding the method. What is the best way to do this?

Here is an example, where "Two" is being returned twice erroneously.

public abstract class Base
{
    public abstract IEnumerable<string> GetUniqueNames();
}

public class Derived : Base
{
    public override IEnumerable<string> GetUniqueNames()
    {
        return new List<string> { "One", "Two" };
    }
}

public class Subderived : Derived
{
    public override IEnumerable<string> GetUniqueNames()
    {
        return base.GetUniqueNames().Concat(new List<string> { "Two", "Three" });
    }
}

I am thinking of returning something like UniqueValueCollection that would throw an exception when a duplicate is attempted to be added. This way other developers will get a hint from name and a descriptive error if they still try to misuse it. Is this a good idea?

PS: I don't need to access the elements by key - it's just an enumerable collection, although UniqueValueCollection<> might use Dictionary<>/HashSet<> behind the scenes.

PPS: maybe a HasSet<> behind an interface? It would be great if it was ordered though.

Den
  • 4,877

1 Answers1

1

The designer of a virtual method will have occasion to worry about an implementer overlooking (or forgetting, as we self-implementers are prone to do) intended details of operation.

Here the intention is a virtual method that returns a container of unique items, possibly strings. The fear is that when implemented, duplicates may occur in the return.

Adopting an expressive naming convention is part of the strategy. A "unique value collection" is a set in mathematics. Of course "set" by itself can be used (as a verb) to indicate returning object members, often accompanied by "get" methods for object members. Many times "SetOf..." or similar phrasing will be chosen to avoid the ambiguity or obscurity of reading "GetSet..." (which might well suggest a polymorphic method).

Beyond merely good names for methods, the designer has some opportunity to impose an interface on the returned value. Here the IEnumerable interface was initially shown, and later the ISet interface was realized to be a better (more restrictive) choice.

hardmath
  • 826