简体   繁体   中英

Handle collection of generics in C#

I need to model in C# a context related to a Taekwondo competition where there is a tournament composed of more matches. Specifically, in relation to the initial number of athletes, a tournament can have at most 3 matches: Eliminatory, Semifinal and Final. In each match, I want to keep track of the Poomsaes (a kind of athlete exhibition) made by the athletes. In an eliminatory or a semifinal match, there is a particular kind of Poomsae with a certain expected result, different in type from the one in a final case (different parameters etc.).

So I have an interface that represents a generic match (which contains Poomsaes capable of handling a specific type of PoomsaeResult). Because of the difficulties of having properties with generic types I divided the concept into two methods.

public interface IMatch<R, P> where R : IPoomsaeResult where P : IPoomsae<R>
{
    void AddScheduledPoomsae(P poomsae);

    ISet<P> GetScheduledPoomsaes();
}

And two implementations, whose interfaces simply are:

public interface IStandardMatch : IMatch<IStandardPoomsaeResult, IStandardPoomsae>
{
}

public interface IFinalMatch : IMatch<IFinalPoomsaeResult, IFinalPoomsae>
{
}

In the Tournament class I would like to have so a dictionary that associates each stage of the tournament (enumeration for Eliminatory, Semifinal and Final) to the related match, in order to achieve something like this:

Dictionary<TournamentStage, IMatch> matches = new Dictionary<TournamentStage, IMatch>();

matches.Add(TournamentStage.Semifinal, new StandardMatch());
matches.Add(TournamentStage.Final, new FinalMatch());

The problem is that IMatch is generic and I must specify a type even if I would like to support any type of match. Can someone with experience in C # suggest solutions to the problem or better ways to model it?


IMatch has two generics because I have modelled IPoomsae with this approach:

public interface IPoomsae<R> where R : IPoomsaeResult
{
    int MemberId { get; }

    R Result { get; }
}

public interface IStandardPoomsae : IPoomsae<IStandardPoomsaeResult>
{
    // Extra
}

public interface IFinalPoomsae : IPoomsae<IFinalPoomsaeResult>
{
    // Extra
}

In fact, each Poomsae has an id related to the athlete who has done it and a kind of result (which is different for standard and final cases).

I would suggest not trying to shoehorn different types of match into one (generic) type. Instead, perhaps:

public class Tournament {
    public Round Eliminatory;
    public Round Semifinal;
    public FinalRound Final;
}

I don't think you need the dictionary either, although you could consider changing the Eliminator and Semifinal above into a list or array of "pre-final" rounds. In any case, the above keeps the types separate so that the results can be separate as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM