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并同时处理手机和相机的最佳选择是什么。
答案 0 :(得分:3)
您遇到的问题是TopLevelResource
无效covariant,即TopLevelResource<PhoneProperties>
不是TopLevelResource<IResourceProperties>
。
您可以通过IDevice
和Phone
来自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);
}
希望这会有所帮助。