2017-10-04 9 views
0

J'ai 2 assemblages (étrangers et locaux). L'assemblage étranger ne peut pas être modifié. Je voudrais étendre une classe étrangère telle qu'elle va maintenant implémenter une interface locale. Est-ce possible en C#?C#: Puis-je étendre une classe étrangère de telle sorte qu'elle implémente une interface locale

EDIT: Je sais que je peux faire ce qui suit:

// foreign.dll 
namespace DX { 
    public struct Vector3 { 
     ... 
    } 
} 

// local.dll 
namespace MyDX { 
    public static class Extensions { 
     public static void MyExtensionMethod(this Vector3 vec, int index){ 
      ... 
     } 
    } 
} 

Ce que je suis intéressé à faire est de forcer la classe/struct étrangères pour mettre en œuvre une interface particulière (sans utiliser l'héritage). Je voudrais utiliser Vector3 comme un type dans une classe générique:

public class MyGeneric<T> where T: IComparable<T> { 
    T _value; 
} 

Le struct ci-dessus: Vector3 ne met pas en œuvre IComparable mais je voudrais utiliser la réflexion pour implémenter l'interface afin que je puisse utiliser la classe étrangère/struct dans sa forme existante (c'est-à-dire sans utiliser l'héritage). L'héritage peut être nécessaire ...

+2

Cela ne peut pas être fait. Pouvez-vous décrire ce que vous voulez réaliser à travers cela? Parce que ça ressemble à un [problème XY] (http://xyproblem.info/) pour moi. – Xiaoy312

+3

'class Local: Etranger, ILocalInterface'? Si vous avez besoin d'utiliser seulement l'interface, il est indifférent de savoir quelle classe l'implémente. – taffer

+1

Que voulez-vous accomplir en faisant cela? – GMR516

Répondre

9

Puis-je prolonger une classe étrangère telle qu'elle implémente une interface locale

Bien sûr, à condition que la classe étrangère ne soit pas scellé. (Et, bien sûr, accessible au projet local, et ainsi de suite.)

// Foreign.DLL 
namespace F 
{ 
    public class B 
    { 
    public void Foo() { } 
    } 
} 

// Local.DLL 
interface IFooBar 
{ 
    void Foo(); 
    void Bar(); 
} 
class D : F.B, IFooBar 
{ 
    public void Bar() { } 
} 

Là, D a étendu F.B, au besoin, et met en œuvre DIFooBar, au besoin. Notez comment F.B.Foo répond à l'obligation contractuelle de IFooBar même si elle est sur la classe de base.

Si la classe étrangère est scellée, vous devrez utiliser la composition plutôt que l'héritage. Cependant, je suis d'accord avec le commentateur qui dit que cela sent comme un problème XY. Pouvez-vous dire quel problème vous êtes vraiment en train de résoudre, plus en détail? Parce qu'il pourrait y avoir une meilleure façon d'accomplir ce que vous voulez.

0

Au sens étroit (comme méthodes d'extension), interfaces d'extension ne sont actuellement pas pris en charge par le langage C#. Mais dans un sens plus large, vous pouvez utiliser l'héritage ou la composition comme expliqué dans la réponse de @ Eric.

La prise en charge des interfaces d'extension en C# a été brièvement discutée en 2015 au Roslyn issue 3357. Toutefois, cela ne peut pas être entièrement implémenté par le compilateur C# seul, car il nécessite le support CLR pour assurer l'égalité de référence entre (ITheAddedInterface)x et x. Le sujet semble être abandonné pour le moment.

D'autres langages CIL tels que F# ont un mécanisme d'extension beaucoup plus flexible que C#. Mais C# rattrape, comme on le voit par exemple. dans C# language issue no. 164 et la vidéo A Preview of C# 8.