有没有办法让现有的类型实现一个接口?

时间:2009-04-29 00:20:40

标签: c# interface

假设我写了一个真正的kick-ass界面。事实上,我想要使用一些我用来实现它们的内置类型,所以无论我编写什么代码使用这个接口都可以使用内置类型。

public interface IKickAss
{
    int Yeahhhhhhh() { get; }
}

public static class Woot
{
    public int Bar(IKickAss a, IKickAss b)
    {
        return a.Yeahhhhhhh - b.Yeahhhhhhh;
    }
}

// What I'd like to do, sort of.
public partial struct Int32 : IKickAss
{
    public int Yeahhhhhhh
    {
        get
        {
            return this;
        }
    }
}

出于多种原因,我多次想要这个。最新的是我已经为“uint”实现了基数排序,但是也创建了一个简单的“IRadixSortable”接口,它需要属性“uint RadixKey {get}”。这意味着我基本上复制了排序代码:一次用于uint数组,另一次用于IRadixSortable数组。我宁愿通过使用uint类型实现IRadixSortable来编写一个。有没有办法做到这一点...也许使用反射?

Haskell可以做到这一点(即类型类可以随时在任何数据类型上实例化),我认为这是它如此强大的一个非常重要的原因。 C#真的可以使用这个功能。也许称之为“扩展接口”:)

6 个答案:

答案 0 :(得分:2)

是和否。

您可能正在寻找Duck Typing,请参阅the following article

答案 1 :(得分:2)

不使用接口,但您可以使用扩展方法执行类似操作。你不会得到“合同”

答案 2 :(得分:0)

仿制药怎么样?基本数字类型都实现ICopmarable,因此您可以编写IComparer实现以传递给数组的Sort方法。

或者也许是一种扩展方法。

答案 3 :(得分:0)

如果您控制实例的创建,您可以从该类继承并在新的继承者类中实现该接口。

答案 4 :(得分:0)

其他人已回答了主要问题,但是对于您的特定基数排序方案,您还可以查看.NET Framework中用于比较,散列等的模式类型:允许您的基数排序方法的用户使用传入一个控制排序顺序的对象。例如。使用RadixKey属性创建一个IRadixKeyProvider接口(类似于IHashCodeProvider或IComparer)。

这并不理想,因为用户每次对集合进行基数排序时都必须传入IRadixKeyProvider,而不是在集合类型上一劳永逸地定义基数键。 (虽然您可以通过为预定义类型创建排序方法的重载来缓解这种情况,这些类型在内部创建了相关的IRadixKeyProvider,然后转发到更通用的方法。)当然它没有解决更一般的场景(是的,我也想要类型类!)。但至少它可以避免重复基数排序代码。

答案 5 :(得分:0)

我看不到内在类型的解决方案,但对于其他类型(即由您或其他人创建的类型),您可以将其子类化并实现您选择的接口。

public interface ISortable
{
    // ... whatever you need to make a class sortable
}

public class ExistingType
{
    // whatever
}

public class NewType : ExistingType, ISortable
{
    // ...
}

除非当然,如果你有权访问现有类型......那就让它实现你的界面。