2010-08-30 10 views
1

Fondamentalement, ce que je veux faire, est la suivante:Espace réservé "Current Type" dans les types génériques C#?

public class MySpecialCollection<T> 
    where T : ISomething { ... } 

public interface ISomething 
{ 
    public ISomething NextElement { get; } 
    public ISomething PreviousElement { get; } 
} 

public class XSomething : ISomething { ... } 

MySpecialCollection<XSomething> coll; 
XSomething element = coll.GetElementByShoeSize(39); 
XSomething nextElement = element.NextElement; // <-- line of interest 

... sans avoir à jeter nextElement à XSomething. Des idées? Je voulais quelque chose dans le genre de ...

public interface ISomething 
{ 
    public SameType NextElement { get; } 
    public SameType PreviousElement { get; } 
} 

Merci à l'avance!

Répondre

10

Faire l'interface générique:

public class MySpecialCollection<T> where T : ISomething<T> { 
    ... 
} 

public interface ISomething<T> { 
    T NextElement { get; } 
    T PreviousElement { get; } 
} 

public class XSomething : ISomething<XSomething> { 
    ... 
} 
+0

Kinda défait le point d'une interface, non? Si vous voulez utiliser cette interface générique, vous devez connaître la classe d'implémentation. – Bubblewrap

+0

@Bubblewrap: Le but est de rendre l'interface retourne la classe d'implémentation, donc vous devez connaître la classe d'implémentation pour l'utiliser quand même. – Guffa

+0

(et James, d'ailleurs): Je pensais déjà que c'était une option, j'espérais juste éviter la construction de la classe publique XSomething: ISomething '- je suis une sorte de base de données, donc des informations redondantes me font mal: -/Mais merci à tous les deux pour cette idée. J'évaluerai les avantages et les inconvénients de rendre l'interface générique plutôt que de lancer le type. – Michael

1

Eh bien, vous pouvez le faire en utilisant un opérateur implicite (bien que je ne suis pas 100% sûr qu'il fonctionnera dans ce cas):

public static XSomething operator implicit(ISomething sth) 
{ 
    return (XSomething)sth; 
} 

Mais notez que cela est évidemment pas une très bonne idée; le moyen le plus propre est de faire une distribution explicite.

+0

D'accord, je ne pensais pas à celui-là. Cependant, comme vous l'avez déjà dit, ce n'est pas une solution très propre (plus je devrais ajouter cela à chaque implémentation de ISomething ..) .. merci quand même pour l'idée :-) – Michael

1

je recommande faire l'interface générique pour que les types de propriétés peuvent être de type générique de l'interface.

using System; 

namespace ConsoleApplication21 
{ 
    public interface INextPrevious<out TElement> 
    { 
     TElement NextElement { get; } 
     TElement PreviousElement { get; } 
    } 

    public class XSomething : INextPrevious<XSomething> 
    { 
     public XSomething NextElement 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public XSomething PreviousElement 
     { 
      get { throw new NotImplementedException(); } 
     } 
    } 

    public class MySpecialCollection<T> 
     where T : INextPrevious<T> 
    { 
     public T GetElementByShoeSize(int shoeSize) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var coll = new MySpecialCollection<XSomething>(); 
      XSomething element = coll.GetElementByShoeSize(39); 
      XSomething nextElement = element.NextElement; 
     } 
    } 
} 
+0

on dirait que Guffa m'a battu :) –

+0

Voir mon commentaire sur Guffas answer :-) – Michael

Questions connexes