泛型:类型'相机'不能用作类型参数' T'在泛型中

时间:2015-02-18 12:03:47

标签: c# generics

interface IResourceProperties
{
}

class TopLevelResource<T> 
where T: IResourceProperties
{

}

class Camera: TopLevelResource<CameraProperties>
{
}

class CameraProperties : IResourceProperties
{
}

class Phone: TopLevelResource<PhoneProperties>
{
}

class PhoneProperties : IResourceProperties
{
}

void Main()
{
 List<Camera> cameras = new List<Camera>();
 List<Phone> phones = new List<Phone>();
 DoSomething(cameras);
 DoSomething(phones);
}

void DoSomething<T>(List<T> items)
where T: TopLevelResource<IResourceProperties>
{
  return;
}

我有上面提到的类层次结构。 通用方法DoSomething需要能够在相机和手机上工作。 但我收到以下错误:

  

类型&#39;相机&#39;不能用作类型参数&#39; T&#39;在通用   类型或方法&#39; DoSomething(System.Collections.Generic.List)&#39;。   来自&#39;服务器&#39;没有隐式参考转换。至   &#39; TopLevelResource&#39;

这表明这是不可能的。

能够一起编写DoSomething并同时处理手机和相机的最佳选择是什么。

2 个答案:

答案 0 :(得分:3)

您遇到的问题是TopLevelResource无效covariant,即TopLevelResource<PhoneProperties>不是TopLevelResource<IResourceProperties>

您可以通过IDevicePhone来自Camera的{​​{1}}界面来解决此问题:

interface IDevice<out T> where T : IResourceProperties

请注意,IDevice<out T>,因此为variant generic interface

<out T>的另一个界面的示例是IEnumerable<out T>。如果TDerived : TBase,那么IEnumerable<TDerived>也是IEnumerable<TBase>IEnumerable<object>

您的代码将是:

interface IResourceProperties
{ }

interface IDevice<out T>
    where T : IResourceProperties
{ }

class TopLevelResource<T> : IDevice<T>
    where T : IResourceProperties
{ }

class Camera : TopLevelResource<CameraProperties>
{ }

class Phone : TopLevelResource<PhoneProperties>
{ }

class CameraProperties : IResourceProperties
{ }

class PhoneProperties : IResourceProperties
{ }

internal class Runner
{
    public static void Run()
    {
        List<Camera> cameras = new List<Camera>();
        List<Phone> phones = new List<Phone>();
        DoSomething(cameras);
        DoSomething(phones);
    }

    static void DoSomething<T>(List<T> items)
        where T : IDevice<IResourceProperties>
    {
        return;
    }
}

答案 1 :(得分:0)

或在手机和相机中实施IResourceProperties

interface IResourceProperties
{
}

class TopLevelResource<T> 
where T: IResourceProperties
{

}

class Camera: TopLevelResource<CameraProperties>, IResourceProperties
{
}

class CameraProperties : IResourceProperties
{
}

class Phone: TopLevelResource<PhoneProperties>, IResourceProperties
{
}

class PhoneProperties : IResourceProperties
{
}



    class Program
    {static void DoSomething<T>
        (List<T> items) where T : IResourceProperties
    {
  return;
}
        static void Main(string[] args)
        {
             List<Camera> cameras = new List<Camera>();
 List<Phone> phones = new List<Phone>();
 DoSomething(cameras);
 DoSomething(phones);
        }

希望这会有所帮助。