2012-06-14 2 views
9

Comment un seul assembly .NET, ciblant 2.0, 3.0, 3.5, 4.0 et 4.5, peut-il prendre en charge des méthodes d'extension pour les clients C# et VB.NET?Escape Catch-22 avec attributs d'extension dans .NET 2.0

La suggestion standard est d'ajouter ceci:

namespace System.Runtime.CompilerServices 
{ 
    public sealed class ExtensionAttribute : Attribute { } 
} 

Cette approche suggérée par more que one Microsoft employee et a même été présenté dans MSDN magazine. C'est widely salué par many bloggers comme n'ayant «aucun effet néfaste».

Oh, sauf que cela provoquera une erreur de compilateur d'un projet VB.NET ciblant .NET 3.5 ou supérieur.

Les auteurs de Microsoft.Core.Scripting.dll figured it out et sont passés de 'public' à 'internal'.

namespace System.Runtime.CompilerServices 
{ 
    internal sealed class ExtensionAttribute : Attribute { } 
} 

Ce qui semblait résoudre le problème de compatibilité VB.

J'ai donc utilisé avec confiance cette approche pour la dernière version (3.2.1) du widely-used ImageResizing.Net library.

Mais puis, nous commençons à obtenir cette erreur du compilateur (original report), plus ou moins au hasard, pour certains utilisateurs ciblant 3.5+ .NET.

Error 5 Missing compiler required member 
'System.Runtime.CompilerServices.ExtensionAttribute..ctor' 

Parce que le compilateur MSBuild/de VisualStudio ne semble pas la peine de regarder les règles de portée lors de la résolution des conflits de noms et l'ordre des références d'assemblage joue un rôle non-tout à fait-docuemented, je ne comprends pas très bien pourquoi et quand cela arrive.

few hacky workarounds Il existe un few hacky workarounds, comme changer l'espace de noms d'assembly, recréer le fichier de projet, supprimer/readding System.Core, et jouer avec la version cible de l'infrastructure .NET. Malheureusement, aucune de ces solutions de contournement ne sont 100% (sauf aliasing, mais c'est une douleur inacceptable).

Comment puis-je résoudre ce problème tout en

  1. Le maintien de soutien à l'utilisation de la méthode d'extension dans l'ensemble,
  2. Maintenir le soutien au 2.0/.NET 3.0
  3. Ne nécessitant pas plusieurs assemblées pour chaque version du framework .NET .

Ou, existe-t-il un correctif pour que le compilateur prenne en compte les règles de portée?

Questions connexes sur SO qui ne répondent pas à cette question

+0

Pouce. Votre prime manque un zéro. Le mieux est de prendre cela en charge avec Microsoft Support, bien qu'ils soient susceptibles de le rejeter avec 'non supporté'. –

Répondre

1

Nous avons rencontré le même problème avec IronPython. http://devhawk.net/2008/10/21/the-fifth-assembly/

Nous avons fini par déplacer notre version personnalisée de ExtensionAttribute vers son propre assembly. De cette façon, les clients peuvent choisir entre référencer notre assembly ExtensionAttribute personnalisé ou System.Core - mais jamais les deux! L'autre problème consiste à toujours déployer l'assembly ExtensionAttribute, même si vous ne le référencez pas dans votre projet. Vos assemblys de projet qui exposent les méthodes d'extension auront une référence d'assembly à cet assembly ExtensionAttribute personnalisé, de sorte que CLR sera perturbé s'il ne peut pas être trouvé. Compte tenu de la forte exigence de support .NET 2.0, je pense que le mieux serait de ne pas utiliser du tout les méthodes d'extension. Je ne suis pas familier avec le projet ImageResizer, mais il semble que ce soit un changement récent dans ImageResizer. Dans quelle mesure serait-il possible de changer les méthodes d'extension en méthodes statiques traditionnelles? Nous avons pensé à cela pour IronPython/DLR, mais ce n'était pas faisable (nous avons été fusionnés avec LINQ à ce moment-là et LINQ avait beaucoup utilisé les méthodes d'extension pour l'essentiel de son existence).

+0

Merci de mettre à jour l'article avec un lien! Je pense que Newtonsoft.Json a eu le même cauchemar que nous ... Trop de blogs disent qu'il n'y a pas de répercussions, et quand j'ai lu le même fait incontesté sur une demi-douzaine de blogs, j'ai supposé que c'était vrai! –

+0

Juste une idée, pourrions-nous nous déplacer avec la transmission de type en quelque sorte? –

+0

Nous aurions encore besoin de plusieurs versions de l'assemblage ... –