我的所有类都实现了一个接口IPrettyPrint。使用扩展方法,我可以将一个PrettyPrint方法添加到一个例如(List<T>
,...)但是有没有可能双重支持IPrettyPrint?任何喜欢使用PrettyPrint方法的人都只能依赖IPrettyPrint。
答案 0 :(得分:3)
不,除非您使用允许“鸭子打字”的库。即便如此,如果方法仅在扩展方法中实现,我认为你很难。
不要被扩展方法所迷惑 - 你没有向类型本身添加任何东西,它们只提供“语法糖”,然后由编译器解释。
答案 1 :(得分:1)
扩展方法是编译器功能,而不是运行时功能 - 它们模拟您向Type
添加方法,但如果您反编译代码,您将看到它实际上没有做任何此类事情( .NET使用静态/封闭类型系统,因此实际向类型添加方法的唯一方法是从类型继承并将方法添加到 new 类型中)
因此,从技术上讲,double
从不支持IPrettyPrint
- 编译器只是假装它。
答案 2 :(得分:0)
可以使用反射模拟鸭子类型 - 如果类型支持操作(即,具有您正在寻找的方法),那么它隐含地是该界面(即使您从未这样做过),并且您应该叫它。否则,它没有!
问题是,C#反射有点慢,在大多数情况下浪费你的时间。示例代码如下:
public static object To(this string value, Type t) {
object obj;
// This is evil, I know, but is the most useful way to extend this method
// without having an interface.
try {
MethodInfo method = t.GetMethod("Parse", BindingFlags.Static | BindingFlags.Public,
null, new Type[] { typeof(string) }, null);
Preconditions.Check(method.ReturnType == t, "The return type doesn't match!");
obj = method.Invoke(null, new object[]{value});
} catch (Exception e) {
throw new CoercionException("I can't coerce " + value + " into a " + t.Name + "!", e);
}
return obj;
}
对于那些喜欢统计数据的人来说,当需要反射时,方法的查找几乎为零。但是,调用方法:
obj = method.Invoke(null, new object[]{value});
性能耗费并且需要大约4-5ms才能执行。