Tom
Tom

Reputation: 1057

Generic Method Constraints?

I have a 2 classes that contain data that will populate separate grids. The grids are very similar, but different enough to require the use of 2 classes. Both grids contain a function called "GetDuplicates" and where I am implementing these classes, I have a method that checks if the class has duplicates and returns a message indicating so.

private bool HasDuplicates(FirstGridList firstList)
{
    var duplicates = firstList.FindDuplicates();
    if (duplicates.Count > 0)
    {
        // Do Something
        return true;
    }
    return false;
}

I would like to be able to call that method using both FirstGridList and SecondGridList. I just don't know how to go about properly implementing the generic constraint then casting the generic input parameter to the correct type. Similar to:

private bool HasDuplicates<T>(T gridList)
{
    // Somehow cast the gridList to the specific type
    // either FirstGridList or SecondGridList

    // Both FirstGridList and SecondGridList have a method FindDuplicates
    // that both return a List<string>
    var duplicates = gridList.FindDuplicates();
    if (duplicates.Count > 0)
    {
        // Do Something
        return true;
    }
    return false;
}

As you can see, the method does the same thing. Therefore I do not want to create this twice. I feel like this is possible, but I am thinking about it incorrectly. I am not exactly experienced with generics yet. Thank you.

Upvotes: 0

Views: 596

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1039488

You could have both your grids implement a common interface like:

public interface IGridList
{
    public IList<string> FindDuplicates();
}

and then define your generic constraint based on this interface:

private bool HasDuplicates<T>(T gridList) where T: IGridList
{
    // Both FirstGridList and SecondGridList have a method FindDuplicates
    // that both return a List<string>
    var duplicates = gridList.FindDuplicates();
    if (duplicates.Count > 0)
    {
        // Do Something
        return true;
    }
    return false;
}

Obviously both your FirstGridList and SecondGridList should implement the IGridList interface and the FindDuplicates method.

or you could even get rid of the generics at this stage:

private bool HasDuplicates(IGridList gridList)
{
    // Both FirstGridList and SecondGridList have a method FindDuplicates
    // that both return a List<string>
    var duplicates = gridList.FindDuplicates();
    if (duplicates.Count > 0)
    {
        // Do Something
        return true;
    }
    return false;
}

By the way at this stage you could even get rid of the HasDuplicates method as it doesn't bring much value to your application. I mean Object Oriented Programming existed long before things like generics or LINQ so why not use it:

IGridList gridList = ... get whatever implementation you like
bool hasDuplicates = gridList.FindDuplicates().Count > 0;

Seems reasonable and readable enough to any developer with basic C# culture. And of course it spares you a couple of lines of code. And remember that the more code you write the higher the probability to make mistakes.

Upvotes: 7

Related Questions