扩展方法和通用约束的问题
我有一个基本接口和几个继承的接口。基接口有一些扩展方法,可以修改对象并返回基类的新实例(IChildA.Touch() => IBase
、IBase.Touch() => IBase
)。
对于一个继承路径(IChildB
和后代),我想实现返回与调用对象类型相同的对象的扩展方法(IGrandChildB.Touch() => IGrandChild
)。为此,我想指定一个仅限于 IChildB
后代的通用扩展方法。
到目前为止,此方法有效,但现在编译器无法解析来自 IChildA
的调用。它尝试使用 IChildB
路径的扩展方法,但失败,而不是使用 IBase
接口的扩展方法。有没有一种优雅的方法来解决这个问题?
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();
}
}
I have a base interface and several inherited interfaces. There are extension methods for the base interface that modify the object and return a new instance of the base class (IChildA.Touch() => IBase
, IBase.Touch() => IBase
).
For one inheritance path (IChildB
and descendants) i want to implement extension methods that return an object of the same type as the calling object (IGrandChildB.Touch() => IGrandChild
). For this i would like to specify a single generic extension method that is constrained to IChildB
descendants.
This works so far, but now the compiler cannot resolve the call from IChildA
. It tries to use the extension method for the IChildB
path and fails instead of using the extension method for the IBase
interface. Is there an elegant way to fix this?
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不知道您的具体用例,但如果您删除非泛型方法并将泛型方法限制为 IBase,该示例仍将编译。
I don't know your concrete use-case, but the example will still compile if you drop the non-generic method and instead constrain the generic method to IBase.