2010-10-23 7 views
2

J'ai une interface de base et plusieurs interfaces héritées. Il existe des méthodes d'extension pour l'interface de base qui modifient l'objet et renvoient une nouvelle instance de la classe de base (IChildA.Touch() => IBase, IBase.Touch() => IBase).Problème avec les méthodes d'extension et les contraintes génériques

Pour un chemin d'héritage (IChildB et descendants), je souhaite implémenter des méthodes d'extension qui renvoient un objet du même type que l'objet appelant (IGrandChildB.Touch() => IGrandChild). Pour cela, je voudrais spécifier une seule méthode d'extension générique qui soit limitée aux descendants IChildB.

Cela fonctionne jusqu'à présent, mais maintenant le compilateur ne peut pas résoudre l'appel de IChildA. Il essaie d'utiliser la méthode d'extension pour le chemin IChildB et échoue au lieu d'utiliser la méthode d'extension pour l'interface IBase. Y a-t-il un moyen élégant de résoudre ce problème?

public interface IBase {} 

public interface IChildA : IBase {} 

public interface IChildB : IBase {} 

public static class BaseExtensions 
{ 
    public static IBase Touch(this IBase self) { return self; } 
    public static T Touch<T>(this T self) where T : IChildB { return self; } 
} 

public static class TestClass 
{ 
    public static void Test() 
    { 
    IChildA a = null; 
    IBase firstTry = a.Touch(); //Cannot resolve to BaseExtensions.DoSomething(this IBase obj) 
    IBase secondTry = ((IBase)a).Touch(); //Resolves to BaseExtensions.DoSomething(this IBase obj) 

    IChildB b = null; 
    IChildB touchedB = b.Touch(); 
    } 
} 

Répondre

1

Je ne connais pas votre cas d'utilisation du béton, mais l'exemple sera encore compiler si vous laissez tomber la méthode non-générique et à la place contraignez la méthode générique pour IBase.

public interface IBase {} 

public interface IChildA : IBase {} 

public interface IChildB : IBase {} 

public static class BaseExtensions 
{ 
    public static T Touch<T>(this T self) where T : IBase { return self; } 
} 

public static class TestClass 
{ 
    public static void Test() 
    { 
     IChildA a = null; 
     IBase firstTry = a.Touch(); 

     IChildB b = null; 
     IChildB touchedB = b.Touch(); 
    } 
} 
Questions connexes