3 votes

Comment appeler un constructeur sur un type générique dans une fonction d'un type de base sans son propre constructeur ?

J'ai pensé qu'un bon moyen de tester ma compréhension des fonctions génériques serait de créer une fonction qui produirait une représentation hexagonale d'un hachage en utilisant l'une des classes qui héritent de HashAlgorithm. Puisque toutes les classes HashAlgorithm offrent ComputeHash, j'ai pensé que ce serait simple. Cependant, lorsque je construis une telle fonction, j'obtiens une erreur car HashAlgorithm lui-même ne propose pas de constructeur. Je n'ai pas trouvé d'interface ou de sous-classe de HashAlgorithm qui offre un constructeur, non plus. Si toutes les classes HashAlgorithm ne sont pas tenues de supporter un constructeur, existe-t-il une contrainte supplémentaire que je peux imposer à un type générique pour m'assurer qu'il offre un constructeur vide ou serai-je obligé de créer une surcharge pour chacune des classes HashAlgorithm dont je sais qu'elles offrent un constructeur vide ?

Voici ce que j'ai jusqu'à présent (dans son état de non-compilation) :

public static string GetHexHash<HashAlgorithmToUse>(Stream dataStreamToHash) where HashAlgorithmToUse : HashAlgorithm
{
    StringBuilder Result = new StringBuilder();
    byte[] ByteHash = (new HashAlgorithmToUse()).ComputeHash(dataStreamToHash);
    foreach (byte HashByte in ByteHash)
    {
        Result.Append(HashByte.ToString("X2"));
    }
    return Result.ToString();
}

Modifier La réponse de Matt Hamilton a tout de suite mis le doigt sur le problème, en rendant simplement la contrainte générique plus complexe : where HashAlgorithmToUse : HashAlgorith, new() . Je n'avais même pas réalisé que je pouvais avoir des contraintes multiples. J'ai définitivement du chemin à faire avant de comprendre pleinement tout ce que je peux faire avec les génériques. Je suppose que vous pouvez créer une fonction générique très peu générique si vous vous laissez trop emporter par les contraintes.

3voto

Matt Hamilton Points 98268

Essayez d'ajouter le new() à la fin de vos contraintes génériques :

public static string GetHexHash<HashAlgorithmToUse>(Stream dataStreamToHash)
    where HashAlgorithmToUse : HashAlgorithm, new()

Cela indique au type que "HashAlgorithmToUse" a un constructeur sans paramètre (par défaut). Cela devrait faire l'affaire.

0voto

Andy Points 15910

Au moins dans Visual Studio 2008, l'ajout de l'option new() à la fonction a permis de la compiler pour moi :

public static string GetHexHash<HashAlgorithmToUse>(Stream dataStreamToHash) where HashAlgorithmToUse : HashAlgorithm, new()
{
    // ...
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X