假设我写了一个真正的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#真的可以使用这个功能。也许称之为“扩展接口”:)
答案 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
{
// ...
}
除非当然,如果你有权访问现有类型......那就让它实现你的界面。