-2

I have several data object classes which all have a member with the same name, I want to create a template class which keeps a List of a specific class as well as some additional information. In the constructor for this template, I want to be be able to iterate through the list and set a member in all of the items.

In C++ this would work because of "duck" typing in templates. How would you do this in C#, (or can you).

Example:

public class Thing1
{
    public string Name {get; set;}
    public string Id {get; set;}
    public string GroupId {get; set;}
}

public class Thing2
{
    public string Size {get; set;}
    public string Id {get; set;}
    public string GroupId {get; set;}
}

public class GroupOfThings<T>
{
    public GroupOfThings(List<T> things, string groupID)
    {
       GroupID = groupID;
       Items = things;
       // This is the code that I would like to be able to have
       // foreach(var i in Items)
       // {
       //     i.GroupId = groupID;
       // }
    }
    public List<T> Items;
    public string GroupId;
}
bpeikes
  • 3,495
  • 9
  • 42
  • 80
  • and what is your problem? From what I see your code should work. As `Items` is `List`, the element `i` should be of type `T`. I suppose you need some generic constraint like `where T: Thing`, assuming both `Thing1` and `Thing2` implement the same interface.# – MakePeaceGreatAgain Dec 16 '20 at 14:15

1 Answers1

3

You need to make an interface that contains the common properties, then have Thing1 and Thing2 inherit from it. Then, add a constraint on your type parameter <T> in GroupOfThings, and you can access the property.

public interface IThing 
{
    string GroupId { get; set; }
}

public class Thing1 : IThing
{
    public string Name {get; set;}
    public string Id {get; set;}
    public string GroupId {get; set;}
}

public class Thing2 : IThing
{
    public string Size {get; set;}
    public string Id {get; set;}
    public string GroupId {get; set;}
}

public class GroupOfThings<T> where T : IThing
{
    public GroupOfThings(List<T> things, string groupID)
    {
       GroupId = groupID;
       Items = things;
       // This is the code that I would like to be able to have
        foreach(var i in Items)
        {
            //compiler knows about GroupId from interface
            i.GroupId = groupID;
        }
    }
    
    public List<T> Items;
    public string GroupId;
}
Jonesopolis
  • 25,034
  • 12
  • 68
  • 112