通用类型,条件松散

时间:2012-11-01 19:47:17

标签: c# generics

我正在构建一个支持通用类型数据插件的应用程序。问题是,我似乎无法指定允许我需要传递的所有内容的通用条件,这里是代码的详细信息:

abstract public class PluginObject<ManagedType>
abstract public class Plugin<EditedType> where EditedType : PluginObject<Object>

这里有<Object>问题,当我创建我的类和插件时,我将创建模型来处理插件的数据方面。为此,我的第一个插件有很多要管理的项目,我无法真正创建它们的子类,所以我最终创建了一个不包含任何内容的接口IOrderObject

因此,我最终得到了:

  1. SynchronizableObject
  2. TripRoute
  3. TripRouteDirection
  4. ITripObject(接口已实现为#2和#3)
  5. 我可以这样做:

    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 PluginObjectpublic 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'

    除非我误解了协方差(可能就是这种情况),否则我似乎已经明确地遵循了你的例子,仍然没有让它运作......

2 个答案:

答案 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和派生类型EmployeePerson实施IPluginObject<out T>。然后,由于协方差,下一个代码是有效的:

IPluginObject<object> myPluginObject = new Employee();

最后,当然,你可以这样做:

public class MyPlugin : Plugin<Employee>
{
}

这是你要找的吗?

查看此MSDN文章,了解有关此主题的更多详细信息:http://msdn.microsoft.com/en-us/library/dd799517.aspx