2010-06-29 147 views
1

我所有的类都实现了一个接口IPrettyPrint。使用扩展方法,我可以将PrettyPrint方法添加到双精度(List<T>,...),但是有没有可能双倍支持IPrettyPrint?任何喜欢使用PrettyPrint方法的人都只能依靠IPrettyPrint。扩展方法和接口

回答

3

不,除非您使用允许“鸭子打字”的图书馆。即使如此,如果该方法仅在扩展方法中实现,我认为你会很困难。

不要被扩展方法愚弄 - 你不向类型本身添加任何东西,它们只提供“语法糖”,然后由编译器解释。

1

扩展方法是一种编译器功能,而不是运行时功能 - 它们模拟您将方法添加到Type,但是如果您反编译代码,您会发现它实际上并没有做任何这样的事情(.NET使用静态/闭式系统,所以实际的方法添加到类型的唯一方法是从类型继承和方法添加到您的型)

因此,技术上,double从不支持IPrettyPrint - - 编译器只是假装它。

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; 
} 

对于那些喜欢stats的人,当需要反射时,该方法的查找接近于无。然而,方法的调用:

obj = method.Invoke(null, new object[]{value}); 

是一个性能猪,大约需要4-5ms执行。