8
votes

Comment permettre un paramètre de type générique pour une méthode C # d'accepter un argument null?

public static void AssertThat<T>(this object testFixture, object actual, Matcher<T> matcher, string message = "")
{
  AssertThat(anyObject, (T)actual, matcher, message);
}

public static void AssertThat<T, TSuper>(this object testFixture, T actual, Matcher<TSuper> matcher, string message = "") where T : TSuper
{
  ... check and assert

7 commentaires

Comment vous attendriez-vous à déduire le type T d'une valeur NULL explicite? Vous pouvez certainement l'utiliser sur une valeur nulle dans une variable de chaîne, mais je ne connais aucun moyen de déduire un type d'une null explicite sans le préciser manuellement.


Eh bien, vous pouvez vous attendre à ce que cela déprète objet .


Et qu'est-ce qui ne va pas avec égalto (null) ? J'essaie de voir le problème pratique .


@Amon - à tout le moins qui semble être un moyen de permettre aux gens de créer des bugs. Je ne connais pas assez de la signature de la correspondance mais je peux penser à plusieurs choses que cela se briserait dans une interface de style fluide en modifiant le type du résultat sans préavis.


@tvanfosson - En fait, c'est exactement ce que je voudrais dans mon scénario spécifique - voir la mise à jour. @Amon - Merci de m'avoir envoyé mon chemin. J'ai un peu compris que les autres réponses étaient affichées. :)


@Gishu - Mon point était que le compilateur, dans ce cas, ne peut pas deviner en toute sécurité ce que vous voulez afin que vous puissiez choisir. Faire Egalto ((objet) null) indique explicitement le compilateur (et le lecteur) exactement ce que vous voulez dire.


@tvanfosson - :) Désolé, je n'ai pas mentionné ça! J'ai compris pourquoi le compilateur a refusé de compiler ce bit sans un coup de pouce d'inférence explicite. Je voulais juste que l'API fonctionne de manière intuitive.


5 Réponses :


2
votes

impossible sans expliquer explicitement un t ou faire une distribution. Les génériques compilent des constructions de temps et telles que telles que le compilateur ne peut pas comprendre le type au moment de la compilation, il ne compilera pas (comme vous voyez).


0 commentaires

0
votes

peut-être implémenter une égalité non générique, qui prend un objet comme type d'argument, résoudrait la question de la réécriture de ces lignes de code.


0 commentaires

2
votes

Puisque vous ne pouvez pas faire exactement ce que vous souhaitez faire, pourquoi ne pas définir un Egalto (objet) méthode surchargée? Cela devrait permettre votre syntaxe requise.


0 commentaires

14
votes

Considérez la méthode suivante:

private static Matcher<object> EqualTo(object item) {
    return new IsEqual<object>(item);
}


1 commentaires

Le dernier bit était exactement ce que j'ai fini par utiliser. Merci!



2
votes

Vous pouvez contourner cette limitation en utilisant la syntaxe suivante: xxx

par défaut (t) est la valeur d'un champ de type t a si non défini. Pour les types de référence, il est null , pour les types de valeur, c'est essentiellement la mémoire remplie de zéro octets (... ce qui peut signifier différentes choses pour différents types, mais signifie généralement une version de zéro).

J'essaie d'éviter le null partout dans mon code aujourd'hui. Il entrave l'inférence de type ailleurs, par exemple avec le champ déclaré déclarée et dans un opérateur ternaire. Par exemple, myarray == null? Par défaut (int?): myarray.length est ok, mais myarray == null? null: myarray.length ne compilera pas.


0 commentaires