我正在努力实现这样的目标:
interface IAbstract
{
string A { get; }
object B { get; }
}
interface IAbstract<T> : IAbstract
{
T B { get; }
}
class RealThing<T> : IAbstract<T>
{
public string A { get; private set; }
public T B { get; private set; }
}
所以我可以这样做:
RealThing<string> rt = new RealThing<string>();
IAbstract ia = rt;
IAbstract<string> ias = rt;
object o = ia.B;
string s = ias.B;
这可能吗?
答案 0 :(得分:10)
非常接近。三件事:
您应该使用new
中的IAbstract<T>
表示您知道自己隐藏了现有成员:
new T B { get; }
但即便没有,你仍然只会收到警告。
您需要在IAbstract.B
中实现RealThing
,您几乎肯定会使用显式接口实现,委托给强类型成员:
object IAbstract.B { get { return B; } }
在测试代码中,您需要为RealThing
指定类型参数:
RealThing<string> rt = new RealThing<string>();
这很好,甚至是一个相当常见的模式,适合您希望能够获得非泛型形式的界面。
答案 1 :(得分:7)
是的,几乎没有变化
interface IAbstract
{
string A { get; }
object B { get; }
}
interface IAbstract<T> : IAbstract
{
new T B { get; }
}
sealed class RealThing<T> : IAbstract<T>
{
public string A { get; private set; }
public T B { get; private set; }
object IAbstract.B
{
get { return B; }
}
}
所以你可以写
var rt = new RealThing<string>();
IAbstract ia = rt;
IAbstract<string> ias = rt;
object o = ia.B;
string s = ias.B;
答案 2 :(得分:1)
实际上System.Collections.IEnumerator
和System.Collections.IEnumerator<T>
接口就是这样做的。实施IEnumerable<T>
时,您必须明确实施其中一个Current
属性,通常您会选择非通用属性:
object IEnumerable.Current
{
// this calls the implicitly implemented generic property
get { return this.Current; }
}
public T Current
{
get { return this.current; } // or however you want to do it
}
答案 3 :(得分:1)
在这种情况下,您甚至不需要两个接口。只需将接口标记为协变(从C#4开始支持):
interface IAbstract<out T>
{
string A { get; }
T B { get; }
}
并在之前使用非通用接口的任何地方使用IAbstract<object>
。