我正在构建一个支持通用类型数据插件的应用程序。问题是,我似乎无法指定允许我需要传递的所有内容的通用条件,这里是代码的详细信息:
abstract public class PluginObject<ManagedType>
abstract public class Plugin<EditedType> where EditedType : PluginObject<Object>
这里有<Object>
问题,当我创建我的类和插件时,我将创建模型来处理插件的数据方面。为此,我的第一个插件有很多要管理的项目,我无法真正创建它们的子类,所以我最终创建了一个不包含任何内容的接口IOrderObject
。
因此,我最终得到了:
SynchronizableObject
TripRoute
TripRouteDirection
ITripObject
(接口已实现为#2和#3)我可以这样做:
public class RoutePluginObject<ManagedType> : Activis.Framework.Admin.PluginObject<ManagedType>
public class RouteManagementPlugin : Activis.Framework.Admin.Plugin<RoutePluginObject<Transdev.Limocar.iTripObject>>
它已被接受,但问题是ITripObject
是一个接口而不是一个对象,所以它可以转换为PluginObject<Object>
。
所以我的问题是,有没有办法指定一个条件,允许类似的东西:
abstract public class Plugin<EditedType> where EditedType : PluginObject<Any>
这样,我可以提供接口或对象,我并不关心这种情况;我想要的只是Plugin
editedtype
PluginObject
为public interface IPluginObject<out ManagedType>
abstract public class Plugin<EditedType> where EditedType : IPluginObject<EditedType>
public class RoutePluginObject : Activis.Framework.Admin.IPluginObject<TripRoute>
public class RouteManagementPlugin : Activis.Framework.Admin.Plugin<RoutePluginObject>
。
修改
使用协方差得到更好的结果但仍然出错,我在你的例子(Matias)中没有看到任何关于PluginObject继承的内容,这就是我所做的:
{{1}}
但我仍然在RouteManagementPlugin上遇到错误:
“Transdev.Limocar.Admin.RoutePluginObject”类型不能用作 泛型类型或方法中的类型参数'EditedType' 'Activis.Framework.Admin.Plugin'。没有隐含的 来自'Transdev.Limocar.Admin.RoutePluginObject'的引用转换 至 'Activis.Framework.Admin.IPluginObject'
除非我误解了协方差(可能就是这种情况),否则我似乎已经明确地遵循了你的例子,仍然没有让它运作......
答案 0 :(得分:3)
您只需要第二个通用参数:
abstract public class PluginObject<ManagedType> {}
abstract public class Plugin<EditedType, OtherType> where EditedType : PluginObject<OtherType>
答案 1 :(得分:1)
您需要协方差。
也就是说,通用参数可以降级。
协方差和逆变只能用于接口和委托通用参数。
在您的情况下,您应该将PluginObject
实现为接口:
public interface IPluginObject<out T>
这将使您的代码能够这样做:
public abstract class Plugin<TEdited> where TEdited : IPluginObject<TEdited>
在一天结束时,假设您有类型Person
和派生类型Employee
。 Person
实施IPluginObject<out T>
。然后,由于协方差,下一个代码是有效的:
IPluginObject<object> myPluginObject = new Employee();
最后,当然,你可以这样做:
public class MyPlugin : Plugin<Employee>
{
}
这是你要找的吗?
查看此MSDN文章,了解有关此主题的更多详细信息:http://msdn.microsoft.com/en-us/library/dd799517.aspx