How to Override List<T>'s Add Method in C#

How do I override ListT's Add method in C#?

First, you can't override Add and still have polymorphism against List, meaning that if you use the new keyword and your class is cast as a List, your new Add method won't be called.

Second, I suggest you look into the Queue class, as what you are trying to do is more of a queue than it is a list. The class is optimized for exactly what you want to do, but does not have any sort of a size limiter.

If you really want something to act like a List but work like a Queue with a maximum size, I suggest you implement IList and keep an instance of a Queue to store your elements.

For example:

public class LimitedQueue<T> : IList<T>
{
public int MaxSize {get; set;}
private Queue<T> Items = new Queue<T>();
public void Add(T item)
{
Items.Enqueue(item);
if(Items.Count == MaxSize)
{
Items.Dequeue();
}
}
// I'll let you do the rest
}

Overriding ListT's Add()

Instead of subclassing from List<T>, you should encapsulate List<T> and implement IList<T>. This makes it easy to handle "overriding" the behavior of Add:

public class ListDemo<T> : IList<T>
{
private List<T> list = new List<T>(); // Internal list
public void Add(T item)
{
// Do your pre-add logic here
list.Add(item); // add to the internal list
// Do your post-add logic here
}

// Implement all IList<T> methods, just passing through to list, such as:
}

List<T> should not be part of your public API - it should be an implementation detail.

Overriding the .Add method in a List of... with validation

If you want uniqueness, use a collection that gives you that: a set.

Make an IEqualityComparer<book> that considers two books to be equal if the Isbns match and use it in a HashSet<Book> that represents your unique list of books:

public class Directory 
{

public HashSet<Book> Books { get; }
= new HashSet<Book>(new BookEqualityComparer());
//...
private class BookEqualityComparer : IEqualityComparer<Book>
{
public bool Equals(Book x, Book y)
{
if (ReferenceEquals(x, y))
return true;

if (ReferenceEquals(x, null) ||
ReferenceEquals(y, null))
return false;

return x.Isbn == y.Isbn;
}

public int GetHashCode(Book obj)
=> obj.Isbn.GetHashCode();
}
}

And you are done, you can't have any duplicate books in Books.

override listT.ToString()

You cannot override a method in some class if you are not inheriting from that class. So the solution is simple - instead of creating name alias, create a class which inherits List<Ponto>:

public class Pontos : List<Ponto>
{
public override string ToString() => $"({String.Join(",", this)})";
}

Or format list in place:

textBox1.Text = $"({String.Join(",", aa)})"; // consider use meaningful names for variables

I would go for the second option if you want to convert pontos list to string only once - string formatting is not a good reason to introduce a new type.


If you need to convert this list to string several times, you can create some private or extension method for formatting list of objects (not necessary Ponto objects). E.g.

public static string Stringify<T>(this IEnumerable<T> values)
=> $"({String.Join(",", values})";

And usage

textBox1.Text = aa.Stringify(); // works with List<int> etc

Links:

  • String.Join - don't use StringBuilder if you want to join items in one string
  • Extension Methods - extend existing classes with new functionality
  • String Interpolation - nice new syntax for formatting strings

Why not inherit from ListT?

There are some good answers here. I would add to them the following points.

What is the correct C# way of representing a data structure, which, "logically" (that is to say, "to the human mind") is just a list of things with a few bells and whistles?

Ask any ten non-computer-programmer people who are familiar with the existence of football to fill in the blank:

A football team is a particular kind of _____

Did anyone say "list of football players with a few bells and whistles", or did they all say "sports team" or "club" or "organization"? Your notion that a football team is a particular kind of list of players is in your human mind and your human mind alone.

List<T> is a mechanism. Football team is a business object -- that is, an object that represents some concept that is in the business domain of the program. Don't mix those! A football team is a kind of team; it has a roster, a roster is a list of players. A roster is not a particular kind of list of players. A roster is a list of players. So make a property called Roster that is a List<Player>. And make it ReadOnlyList<Player> while you're at it, unless you believe that everyone who knows about a football team gets to delete players from the roster.

Is inheriting from List<T> always unacceptable?

Unacceptable to whom? Me? No.

When is it acceptable?

When you're building a mechanism that extends the List<T> mechanism.

What must a programmer consider, when deciding whether to inherit from List<T> or not?

Am I building a mechanism or a business object?

But that's a lot of code! What do I get for all that work?

You spent more time typing up your question that it would have taken you to write forwarding methods for the relevant members of List<T> fifty times over. You're clearly not afraid of verbosity, and we are talking about a very small amount of code here; this is a few minutes work.

UPDATE

I gave it some more thought and there is another reason to not model a football team as a list of players. In fact it might be a bad idea to model a football team as having a list of players too. The problem with a team as/having a list of players is that what you've got is a snapshot of the team at a moment in time. I don't know what your business case is for this class, but if I had a class that represented a football team I would want to ask it questions like "how many Seahawks players missed games due to injury between 2003 and 2013?" or "What Denver player who previously played for another team had the largest year-over-year increase in yards ran?" or "Did the Piggers go all the way this year?"

That is, a football team seems to me to be well modeled as a collection of historical facts such as when a player was recruited, injured, retired, etc. Obviously the current player roster is an important fact that should probably be front-and-center, but there may be other interesting things you want to do with this object that require a more historical perspective.

Override only Get accessor

If at first you have defined a read-only property in a type, you can't later change it to a read/write property in a derived class. That's simply how .NET works, and can't be changed.

If, on the other hand, you define an interface with a read-only property, you can later implement that interface in a class with a writable property.

If you'd like to share what you are trying to achieve, perhaps we can come up with a design that works and can compile :)

How to overwrite list?

Instead of overwriting the list, why not just clear your list and then start adding items.

Clear your list by using the following method:

myList.Clear();

and then add items in your list:

myList.add(item);

EDIT

If you want to keep the old values, then once the list is filled with 10 items, add a new item at first index as shown below:

myList[0] = (newItem);  

newItem will overwrite the first item in your list

How to initialize a list of strings (Liststring) with many string values

List<string> mylist = new List<string>(new string[] { "element1", "element2", "element3" });


Related Topics



Leave a reply



Submit