Rui Martins
Rui Martins

Reputation: 2184

Deleting from a generic list

I have this problem with lists and I can't seem to fix it

I have this class that implement a interface that has the following method.

public List<T> CalculateWad<T, TH>(
    List<T> outputList,
    List<TH> inputList,
    bool flag)
{
    ...
}

Now, I have a outputlist and a inputlist with a common field Contract. I need to delete in outputlist all contracts that exist in inputlist.

It has to be as generic as possible. I can't seem to be able to get the fields of the lists.

Any ideas?

Upvotes: 0

Views: 90

Answers (3)

Cyril Gandon
Cyril Gandon

Reputation: 17048

In order to access the Contract property, the generics T and TH must implement an interface with the Contract property.

Documentation : where (generic type constraint) (C# Reference)

interface IContractable { string Contract { get; } }

Then your class containing the CalculateWad method must be define as follow :

class MyClass<T, TH>
    where T : IContractable
    where TH : IContractable
{
    public List<T> CalculateWad(List<T> outputList, List<TH> inputList, bool flag)
    {
        return outputList
                  .Where(o => 
                      inputList.Select(i => i.Contract).Contains(o.Contract) == false)
                  .ToList();
    }
}

Upvotes: 3

Matthias Meid
Matthias Meid

Reputation: 12513

This should to the job, by adding a common IHasContract interface that both T and TH must implement:

class Program
{
    static void Main(string[] args)
    {
    }

    private IList<T> CalculateWad<T, TH>(IList<T> output,
        IList<TH> input, bool flag)
        where T : IHasContract
        where TH : IHasContract
    {
        var contracts = new HashSet<string >(input.Select(i => i.Contract));

        var qry = from o in output
                  where !contracts.Contains(o.Contract)
                  select o;

        return qry.ToList();
    }

    private sealed class Contract
    {

    }

    private interface IHasContract
    {
        string Contract { get; }
    }

    private sealed class Foo : IHasContract
    {
        public string Contract { get; set; }
    }

    private sealed class Bar : IHasContract
    {
        public string Contract { get; set; }
    }
}

Note that is does not modify output, which you mention in the text. It does, however, return a new altered copy of the list, which may be rather what the method signature describes.

Upvotes: 2

The Coordinator
The Coordinator

Reputation: 13137

So this is your interface:

public List CalculateWad( List outputList, List inputList, bool flag) { ... }

And you need to do this? Assumes that the objects in each list can be compared by their equals method.

public List<T> CalculateWad<T, TH>( List<T> outputList, List<TH> inputList, bool flag) {

              // cast list to be regular object lists
              List out = (List) outputList;
              List in = (List) inputList;

              for(Object object : in){
                  out.remove(object);  // this looks for an object that matches using contract.equals(object)         
              }
}

What is flag variable for?

Upvotes: 0

Related Questions