does it violate the principal of least astonishment to return a List
of authors sorted by last name?
Any practical implementation will astonish you! scroll down to read more!!
Maybe its not impossible to write a getter that works 'as expected' but naive implementations quickly fall over. I'm going to stick with the (less confusing) C#.
public class Book
{
private HashSet<string> authors;
public Book(HashSet<string> authors)
{
this.authors = authors;
}
private List<string> cachedAuthors;
public List<string> Authors
{
get
{
//avoid sorting every time we get the value!
if(cachedAuthors == null)
{
cachedAuthors = this.authors.ToList();
cachedAuthors.Sort();
}
return this.cachedAuthors;
}
set
{
//make sure our set remains in sync!
this.authors = new HashSet<string>(value.Distinct());
cachedAuthors = this.authors.ToList();
cachedAuthors.Sort();
}
}
}
tests:
var auth = new HashSet<string>(new[] { "h", "j", "l" });
var b = new Book(auth);
Console.WriteLine(string.Join(",", b.Authors)); //h,j,i as expected
b.Authors.Add("a");
Console.WriteLine(string.Join(",", b.Authors)); //h,j,i,a whhhaaaa?!?!
b.Authors = new List<string>() { "z", "y", "x" };
Console.WriteLine(string.Join(",", b.Authors)); //x,y,z as expected
b.Authors = new List<string>() { "a", "a", "a" };
Console.WriteLine(string.Join(",", b.Authors)); //a whhaaa??!?!?!?!?!
b.Authors.Add("a");
b.Authors.Add("a");
Console.WriteLine(string.Join(",", b.Authors)); //a,a,a whhhaaaa??!!!!!
So what do we expect from authors? that it always be alphabetically sorted? that there not be duplicates? should we be able to alter it?
If you want these things simply changing to a list isn't for you.
In the comments you say you want a UI to display a sorted list of authors. But you don't need or want your model to do that sorting for you. It is a UI Concern. you can simply order it as desired in the UI layer
Console.WriteLine(string.Join(",", b.Authors.OrderBy(i=>i.LastName).ThenBy(i=>i.Firstname));