2010-10-29 4 views
1

En supposant qu'il SUIVEZ interfacesListes de types dans les génériques de C#: est-ce possible?

public interface IRoot 
{ 
    IChildA ChildA { get; } 
    IChildB ChildB { get; } 
} 
public interface IChildA 
{ 
    IGrandChildA GrandChildA { get; } 
    IGrandChildB GrandChildB { get; } 
} 
public interface IChildB 
{ 
    IGrandChildC GrandChildC { get; } 
} 
public interface IGrandChildA 
{ 
} 
public interface IGrandChildB 
{ 
} 
public interface IGrandChildC 
{ 
} 

Je voudrais écrire de style couramment « configurateur » afin de garder les associations d'interface. Tout devrait ressembler à ceci:

private static void Test() 
{ 
    Configurator.Root<IRoot>() 
    .Join(_ => _.ChildA) 
    .Join(_ => _.GrandChildA) 
    .Up() 
    .Join(_ => _.GrandChildB) 
    .Up() 
    .Up() 
    .Join(_ => _.ChildB); 
} 

Il est nécessaire d'autoriser le niveau d'imbrication arbitraire des paires Join/Up. Voici ma tentative de déclarer un tel configurateur.

public static class Configurator 
{ 
    public static IConfigBuilder<T, T> Root<T>() 
    { 
    return null; 
    } 
} 
public interface IConfigBuilder<P, T> 
{ 
    IConfigBuilder<T, C> Join<C>(Expression<Func<T, C>> expression); 
    IConfigBuilder<???, P> Up(); // This is the problem. How can I get grand-parent type? 
} 

Il m'est difficile de me souvenir de tous les types de nœuds précédents. En d'autres termes, comment déclarer la méthode Up()? Cela me rappelle les bonnes listes de types d'Alexandrescu en C++. Est-il possible de réaliser la même chose dans .net?

Répondre

1

Vous auriez besoin d'au moins deux interfaces; et plutôt que de renvoyer IConfigBuilder<...> pour Up, faites confiance au code de création pour savoir ce qu'il a créé:

public interface IConfigBuilder<T> 
{ 
    IConfigBuilder<IConfigBuilder<T>, C> Join<C>(Expression<Func<T, C>> expression); 
} 
public interface IConfigBuilder<P, T> : IConfigBuilder<T> 
{ 
    P Up(); // This is the problem. How can I get grand-parent type? 
    new IConfigBuilder<IConfigBuilder<P, T>, C> Join<C>(Expression<Func<T, C>> expression); 
}