具有泛型 class 类型约束的泛型方法
Generic method with generic class type constraint
我有一个通用接口,它有一个带有另一个通用类型的方法。
该方法的约束应该只允许从 class 的泛型派生的类型。我尝试了以下代码和其他一些可能性,但 none 目前有效:
generic <class ObjectType>
public interface class IFoo
{
public:
generic <class ObjectTypeInherited> where ObjectTypeInherited : ObjectType
ObjectTypeInherited Test();
};
public ref class Derived : IFoo<System::Object^>
{
public:
generic <class ObjectTypeInherited> where ObjectTypeInherited : System::Object^
virtual ObjectTypeInherited Test()
{
return ObjectTypeInherited();
}
};
int main(array<System::String ^> ^args)
{
auto derived = gcnew Derived();
auto nullString = derived->Test<System::String^>();
if (nullString == nullptr)
System::Console::WriteLine("Got a null string!");
return 0;
}
我的代码收到以下错误:
error C3766: 'Derived' must provide an implementation for the interface
方法'ObjectTypeInherited IFoo::Test(void)'
如果我将其更改为:
generic <class ObjectTypeInherited> where ObjectTypeInherited : System::Object^
我收到一个不同的错误:
error C3284: the constraints for generic parameter 'ObjectTypeInherited' of function 'ObjectTypeInherited Derived::Test(void)' must match the constraints for generic parameter 'ObjectTypeInherited' of function 'ObjectTypeInherited IFoo<System::Object ^>::Test(void)'
有人知道如何正确实施吗?
编辑:System::Object^ 和 System::String^ classes 仅用作这里的例子。通常我会使用 2 个自己的 ref class 像 MyObject 和 MyDerivedObject : MyObject
首先
generic <class ObjectTypeInherited> where ObjectTypeInherited : System::Object^
。
应该
generic <class ObjectTypeInherited> where ObjectTypeInherited : System::Object
.
没有^
在这里签名。
然后乐趣开始了...
不知何故,C++\CLI
编译器不希望理解 class 不必是通用的才能实现 IFoo<ObjectType>::Test
。所以我为这个奇怪的问题创建了一个解决方法。
您可以使用 System::Object
而不是 MyObjectType
。我使用 MyObjectType
只是为了多功能性。
public ref class MyObjectType
{
};
generic <class ObjectType>
public interface class IFoo
{
public:
generic <class ObjectTypeInherited> where ObjectTypeInherited : ObjectType
ObjectTypeInherited Test();
};
//All the magic is here. Somehow the C++\CLI compiler does not wish to
//understand that the DerivedBase class does not have to be generic in order
//to implement the IFoo<ObjectType>::Test. As you can see the Whatever type
//name is never used. Although without it the compiler gives the C3284
//error.
generic <class Whatever>
public ref class DerivedBase : public IFoo<MyObjectType^>
{
public:
//Why not make use of explicit syntax just because we can.
generic <class ObjectTypeInherited> where ObjectTypeInherited : MyObjectType
virtual ObjectTypeInherited Test() = IFoo<MyObjectType^>::Test
{
return ObjectTypeInherited();
}
};
//In order to overcome the fake genericness of DerivedBase I provide
//another successor.
public ref class Derived : public DerivedBase<Object^>
{
};
我对 Roslyn 编译器或 C++\CLI 没有任何深入的了解,但在我看来这似乎是一个错误。
如果我对 C# 托管代码执行相同的操作,它应该看起来像这样简单。这就是我要阻止自己的地方。即使没有任何奇怪的编译器行为,托管声明在 C# 端也比 C++\CLI 更容易维护。
public class MyObjectType
{
}
public interface IFoo<ObjectType>
{
ObjectTypeInherited Test<ObjectTypeInherited>() where ObjectTypeInherited : ObjectType;
}
public class Derived : IFoo<MyObjectType>
{
//Explicit
ObjectTypeInherited IFoo<MyObjectType>.Test<ObjectTypeInherited>()
{
return null;
}
//Implicit
public ObjectTypeInherited Test<ObjectTypeInherited>() where ObjectTypeInherited : MyObjectType
{
return null;
}
}
我有一个通用接口,它有一个带有另一个通用类型的方法。 该方法的约束应该只允许从 class 的泛型派生的类型。我尝试了以下代码和其他一些可能性,但 none 目前有效:
generic <class ObjectType>
public interface class IFoo
{
public:
generic <class ObjectTypeInherited> where ObjectTypeInherited : ObjectType
ObjectTypeInherited Test();
};
public ref class Derived : IFoo<System::Object^>
{
public:
generic <class ObjectTypeInherited> where ObjectTypeInherited : System::Object^
virtual ObjectTypeInherited Test()
{
return ObjectTypeInherited();
}
};
int main(array<System::String ^> ^args)
{
auto derived = gcnew Derived();
auto nullString = derived->Test<System::String^>();
if (nullString == nullptr)
System::Console::WriteLine("Got a null string!");
return 0;
}
我的代码收到以下错误:
error C3766: 'Derived' must provide an implementation for the interface
方法'ObjectTypeInherited IFoo::Test(void)'
如果我将其更改为:
generic <class ObjectTypeInherited> where ObjectTypeInherited : System::Object^
我收到一个不同的错误:
error C3284: the constraints for generic parameter 'ObjectTypeInherited' of function 'ObjectTypeInherited Derived::Test(void)' must match the constraints for generic parameter 'ObjectTypeInherited' of function 'ObjectTypeInherited IFoo<System::Object ^>::Test(void)'
有人知道如何正确实施吗?
编辑:System::Object^ 和 System::String^ classes 仅用作这里的例子。通常我会使用 2 个自己的 ref class 像 MyObject 和 MyDerivedObject : MyObject
首先
generic <class ObjectTypeInherited> where ObjectTypeInherited : System::Object^
。
应该
generic <class ObjectTypeInherited> where ObjectTypeInherited : System::Object
.
没有^
在这里签名。
然后乐趣开始了...
不知何故,C++\CLI
编译器不希望理解 class 不必是通用的才能实现 IFoo<ObjectType>::Test
。所以我为这个奇怪的问题创建了一个解决方法。
您可以使用 System::Object
而不是 MyObjectType
。我使用 MyObjectType
只是为了多功能性。
public ref class MyObjectType
{
};
generic <class ObjectType>
public interface class IFoo
{
public:
generic <class ObjectTypeInherited> where ObjectTypeInherited : ObjectType
ObjectTypeInherited Test();
};
//All the magic is here. Somehow the C++\CLI compiler does not wish to
//understand that the DerivedBase class does not have to be generic in order
//to implement the IFoo<ObjectType>::Test. As you can see the Whatever type
//name is never used. Although without it the compiler gives the C3284
//error.
generic <class Whatever>
public ref class DerivedBase : public IFoo<MyObjectType^>
{
public:
//Why not make use of explicit syntax just because we can.
generic <class ObjectTypeInherited> where ObjectTypeInherited : MyObjectType
virtual ObjectTypeInherited Test() = IFoo<MyObjectType^>::Test
{
return ObjectTypeInherited();
}
};
//In order to overcome the fake genericness of DerivedBase I provide
//another successor.
public ref class Derived : public DerivedBase<Object^>
{
};
我对 Roslyn 编译器或 C++\CLI 没有任何深入的了解,但在我看来这似乎是一个错误。
如果我对 C# 托管代码执行相同的操作,它应该看起来像这样简单。这就是我要阻止自己的地方。即使没有任何奇怪的编译器行为,托管声明在 C# 端也比 C++\CLI 更容易维护。
public class MyObjectType
{
}
public interface IFoo<ObjectType>
{
ObjectTypeInherited Test<ObjectTypeInherited>() where ObjectTypeInherited : ObjectType;
}
public class Derived : IFoo<MyObjectType>
{
//Explicit
ObjectTypeInherited IFoo<MyObjectType>.Test<ObjectTypeInherited>()
{
return null;
}
//Implicit
public ObjectTypeInherited Test<ObjectTypeInherited>() where ObjectTypeInherited : MyObjectType
{
return null;
}
}