在C#项目中,我有以下几种类型:
public struct Struct<T> { public T Field; }
public interface IInterface<T>
{
T F(T x);
}
public abstract class Class<T> : IInterface<T>, IInterface<Struct<T>> {
virtual public T F(T x) { return x; }
virtual public T F(Struct<T> x) { return x.Field; }
Struct<T> IInterface<Struct<T>>.F(Struct<T> x) { return default(Struct<T>); }
}
在C ++ / CLI项目中,我想继承Class<T>
并覆盖虚拟F
方法:
public ref class Derived sealed : public Class<int> {
public:
virtual int F(Struct<int> x) override;
};
不幸的是,这不起作用:
error C2553: 'int Derived::F(Struct<T>)': overriding virtual function return type
differs from 'Struct<T> IInterface<Struct<T>>::F(Struct<T>)'
with
[
T=int
]
因此看起来编译器想要覆盖显式接口实现而不是虚拟方法。
我尝试了几种变体,但都没有效果。有时我只是得到
error C3671: 'Derived:F' : function does not override 'IInterface<T>::F'
如何指定要覆盖的正确方法?
更新
如果我添加IInterface::F
的显式接口实现,正如Ken在下面建议的那样,那么错误消息就会消失。
看起来这是一个C ++ / CLI编译器错误:我不应该重新实现一个接口。
不幸的是,虽然这是解决方案的良好开端,但问题并未完全解决:
如果我将Derived::F
称为IInterface
,则会调用Derived
的显式实现(IInterface_F
)。如果我可以将调用从基类传递给实现,那么这可以解决这个问题。
所以我接下来的问题是:如果我有一个具有相同签名的重载(返回类型除外),我如何从基类调用显式接口实现,并且还定义了相同接口的显式实现。衍生类?
换句话说,如果我有C#:
public interface IInterface {
int F(int x);
}
public class A : IInterface {
virtual long F(int x) { return 1L; }
int IInterface.F(int x) { return 3; }
}
并在C ++ / CLI中:
public ref class B : A {
public:
virtual long F(int x) override { return 2L; }
virtual int IInterface_F(int x) sealed = IInterface::F {
return ??? // call A's version of IInterface::F(x), which returns three
}
}
如何从A
拨打IInterface::F
的{{1}}版本?
答案 0 :(得分:1)
使用您提供的代码(虽然Class<T>
对我来说很奇怪):
public ref class Derived sealed : public Class<int> {
public:
virtual int F(Struct<int> x) override;
};
编译器抱怨:
错误C2553:'int Derived :: F(Struct)':覆盖虚函数返回类型不同于'Struct IInterface&gt; :: F(Struct)'
with [ T=int ]
错误C3766:'派生'必须为接口方法'Struct IInterface&gt; :: F(Struct)'提供实现
with [ T=int ]
错误C3612:'派生':密封类不能有任何纯虚方法 必须定义以下方法:
'Struct IInterface>::F(Struct)' : is abstract with [ T=int ]
所以我认为提供接口方法的实现,因为编译器只是解决了问题:
public ref class Derived sealed : public Class<int> {
public:
virtual Struct<int> IInterface_F(Struct<int> x)
sealed=IInterface<Struct<int>>::F {
return Struct<int>(); // equivalent to default(Struct<int>) in c#
}
virtual int F(Struct<int> x) override {
return 0; // equivalent to default(int) in c#
}
};