11
votes

Spécification des paramètres de type C #

Certains types de CLI spéciaux de mscorlib bibliothèque ( argitterator , TypeReference et runtimeargumenthandle types) ne peuvent pas être utilisés comme Paramètres de type générique Pour construire les types / méthodes génériques: xxx

fournit l'erreur du compilateur: xxx

mais cela n'est pas documenté du tout dans La spécification C #.

Est-ce que ces types sont une partie de la spécification CLI ou de ces types fournies par la mise en oeuvre CLR et le comportement décrit ci-dessus ne doit pas être documenté à la spécification C #?


1 commentaires

Et non négligé, pas aussi surprenant.


5 Réponses :


7
votes

Je crois que c'est parce que ces types sont "spéciaux" en ce qu'ils ne peuvent pas être convertis en objet ; Seuls les types pouvant être convertis en objet peuvent être spécifiés comme des arguments de type. La même chose est vraie pour les pointeurs, au fait.

Je ne trouve pas où cela est documenté (il est documenté pour les pointeurs dans 4.4.1) mais Eric Lippert l'a mentionné dans un commentaire l'autre jour.

est-ce juste une question d'intérêt ou essayez-vous de faire quelque chose en utilisant ce genre de chose?


1 commentaires

Bien sûr, ce n'est que des intérêts et des exemples synthétiques, je testais un code générique avec tous les valeurs de valeur de Mscorlib et fondé ce problème, mais je n'ai trouvé aucune explication dans C # Spec ... Je comprends que ce type est très spécial, l'argataires est en fait Une structure avec la taille varie ... mais pas d'explication! :)



1
votes

Les trois exemples que vous avez fournis sont des structures et non des cours, donc je soupçonne que c'est la clé du problème. Un exemple fourni dans la documentation sur le Message d'erreur du compilateur indique également que Si vous utilisez un pointeur sur un type dans le générique, cela échouerait.


1 commentaires

Les structures sont autorisées et l'argataires, pour un, ne contient aucun pointeur. J'ai essayé une structure personnalisée contenant des champs IntPTR et cela fonctionne bien. En difficulté pour voir ce qui cause l'erreur. Peut-être est-il lié aux méthodes externes ou dangereuses.



10
votes

Tout d'abord, Jon est à nouveau correct - ces gars-là sont types très spéciaux dont les valeurs ne sont pas convertibles à l'objet, et ne peuvent donc pas être utilisés comme arguments de type. Tous les arguments de type doivent être des types dont les valeurs sont convertibles à l'objet.

Pour répondre à votre question sur la documentation:

Aucune des fonctionnalités spéciales pour la manipulation des méthodes variadiques est documentée. Ils ne font pas partie de la langue C # elle-même - une implémentation conforme de la langue n'est pas nécessaire pour pouvoir se faire interoper avec des langues prenant en charge les méthodes variadiques. Ces fonctionnalités ne sont pas non plus documentées dans MSDN dans le cadre de la documentation du compilateur. Ce ne sont pas des fonctionnalités «officiellement pris en charge».

Ceci est regrettable, mais il n'ya que trop de budget disponible, et je pense que la plupart des gens conviendront que nous ferions mieux d'écrire des fonctionnalités et de résoudre des bugs que de dépenser des fonctionnalités de documentation de l'argent que 99,99% de nos utilisateurs ne seront jamais, jamais utiliser même s'ils étaient soutenus, ce qu'ils ne sont pas.

Si vous voulez aller faire interoper en C # avec des méthodes variadiques, vous êtes seul. Bonne chance!


1 commentaires

J'avais tort de penser que ces caractéristiques sont "officielles". Merci, Eric! :)




1
votes

Tout comme un commentaire, voici un peu plus amusant que vous pouvez avoir lorsque vous essayez de compiler le code avec ce type qui n'est pas convertible à l'objet. Toutes les méthodes présentées ici comme suggestions de Visual Studio lorsque vous tapez le . Code> (point).

  ArgIterator.ReferenceEquals(new object(), new object());  // OK; static method inherited from System.Object

  var strange = default(ArgIterator);
  strange.End();          // OK; non-virtual method defined in the struct
  strange.GetHashCode();  // OK; method overridden in the struct
  strange.ToString();     // compile-time error; method overriden in System.ValueType, inherited but not overridden in the struct
  strange.GetType();      // compile-time error; non-virtual method inherited from System.Object


0 commentaires