实现通用接口

时间:2010-10-11 13:55:14

标签: c# interface implementation generics

我有一个通用界面:

public interface IUnauthorizedRequestRespondable<out T> where T:class 
{
    T GetResponseForUnauthorizedRequest();
}  

(我不确定为什么Resharper推荐T是“out”,但这不是问题。)
在我的场景中,GetResponseForUnauthorizedRequest返回的对象始终是实现接口的类型。

所以接口的所有实现都是这样的:

public class SignInReturnedObject : IUnauthorizedRequestRespondable<SignInReturnedObject>  

(类名和括号中的类型始终相同) 这看起来有点尴尬 - 是不是有一种更简洁的方式来告诉编译器接口的方法返回它所属的类型?

感谢。

5 个答案:

答案 0 :(得分:4)

据我所知,目前在C#中无法做到这一点。

理论旁注:允许您执行此操作的功能称为自我类型,但在C#中不可用。该功能的想法是你有一个特殊类型引用this的实际类型,所以如果你有一个名为self的特殊类型,你可能会写一些类似的东西:

public interface IUnauthorizedRequestRespondable { 
    self GetResponseForUnauthorizedRequest(); 
}   

...当您有一个实现接口的类self时,用SignInReturnedObject代替的实际类型将是SignInReturnedObject,但不幸的是,这不是
可在C#中找到: - )

答案 1 :(得分:2)

如果你想以这种方式使用该模板的唯一方法,我会使用:

public interface IUnauthorizedRequestRespondable<T> where T:IUnauthorizedRequestRespondable<T>
{
    T GetResponseForUnauthorizedRequest();
}

这样做的好处是可以保证不会以任何其他方式使用它。

班级宣言不会改变,但我自己并没有看到任何尴尬。考虑到您正在定义类与其自身之间的关系,任何更简洁的形式都可能是不可取的。

答案 2 :(得分:0)

实际上,关于总结它。这就是语法的工作原理。

您可以在.NET本身使用IEquatable接口看到它 - 您几乎总是将对象与自身进行比较,但您始终必须提供自己的类名作为模板参数。

这只是为了提供灵活性,以便您可以与任何事物进行比较,而不一定是您自己。

答案 3 :(得分:0)

您可以创建非通用版本并使用它,但我认为它比它的价值更麻烦

public interface ICastUnauthorizedRequestRespondable : IUnauthorizedRequestRespondable<SignInReturnedObject>
{
}  

答案 4 :(得分:0)

由于T可以是任何类(不必是您正在实现的类),因此您需要为您的类命名。

public class SignInReturnedObject : IUnauthorizedRequestRespondable<ANYCLASS>