If you think about it in terms of real life, you have a Deck that contains instances of Card. The cards in the deck all have the same types of qualities or physical features; they all have a Suit and a Number, and in your business situation, they all have a Value. They are structurally identical; the only difference is in the values for each of the characteristics.
There's no point to build more sub-classes or even interfaces for these Cards if they all have the same properties and behaviours.
We use inheritance and composition (Interfaces) in software design to add attributes and behaviours to the underlying implementation, as well as to change existing behaviour. Inheriting from a Card solely to change the values of the characteristics is an anti-pattern that might lead to misunderstanding later on. The concept of structure vs. content must be clearly distinguished. If the structure and behaviour are in good working order,
You've also defined a list of suits and declared that they have specific integer values; in C#, such fixed lists can be encapsulated with an enum.
public enum Suit : int
{
Red = 1,
Blue = 2,
Green = 3,
Yellow = 4
}
public class Deck
{
private List<Card> deckList;
}
public class Card
{
public Suit Suit { get; private set; }
public int Number { get; private set; }
public Card (Suit suit, int number)
{
this.Suit = suit;
this.Number = number;
}
public int Value { get { return (int)Suit * Number; } }
}
We can now design a way to manufacture a deck of cards for us based on some predetermined criteria, which I'll refer to as:
public class Deck
{
private const int LENGTH_OF_SUIT = 10;
private List<Card> deckList = new List<Card>();
public Deck()
{
BuildDeck();
}
private void BuildDeck()
{
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
for(int number = 1 ; number <= LENGTH_OF_SUIT; number ++)
{
deckList.Add(new Card(suit, number));
}
}
}
}
You may play with this simple structure here: https://dotnetfiddle.net/BnhGGG