上下文:.NET 4.0,C#
我正在创建一组接口和一组实现它们以提供某些服务的clases.客户端使用具体的clases,但调用使用interfaces作为参数类型声明的方法.
一个简化的例子就是这个:
namespace TestGenerics
{
// Interface, of fields
interface IField
{
}
// Interface: Forms (contains fields)
interface IForm<T> where T : IField
{
}
// CONCRETE CLASES
class Field : IField
{
}
class Form <T> : IForm<T> where T : IField
{
}
// TEST PROGRAM
class Program
{
// THIS IS THE SIGNATURE OF THE METHOD I WANT TO CALL
// parameters are causing the error.
public static void TestMethod(IForm<IField> form)
{
int i = 1;
i = i * 5;
}
static void Main(string[] args)
{
Form<Field> b = new Form<Field>();
Program.TestMethod(b);
}
}
}
Run Code Online (Sandbox Code Playgroud)
代码对我有意义,但我得到编译器错误:
参数1:无法从'
TestGenerics.Form<TestGenerics.Field>' 转换为'TestGenerics.IForm<TestGenerics.IField>'TestGenerics
我不确定我做错了什么,我在互联网上阅读了很多页面,但没有解决我的问题.
是否有一个解决方案不会修改我正在尝试构建的架构:
编辑:我设计接口的方式使它们应该独立于实现它们的具体条款.可以从dll加载具体的clases,但是大多数应用程序都可以使用接口.在某些情况下,我需要使用具体的clases,特别是在使用需要序列化的clases时.
提前致谢.
亚历杭德罗
D S*_*ley 13
问题是Form<Field>实现IForm<Field>但不是IForm<IField>.您不能将继承的类(或接口)用作泛型参数,除非它被标记为与out标识符的协变.但是,将您的界面标记为协变将显着限制使用(基本上是在"仅输出"界面中制作IEnumerable)因此它可能对您不起作用.
让它工作的一种方法是制作TestMethod通用:
public static void TestMethod<T>(IForm<T> form) where T:IField
{
int i = 1;
i = i * 5;
}
Run Code Online (Sandbox Code Playgroud)
Tam*_*eer 10
您可以使用协方差,如下所示:
interface IForm<out T> where T : IField
{
}
Run Code Online (Sandbox Code Playgroud)
有关协方差和逆变的更多信息,请点击此处.
其他人已经指出了错误消息背后的原因,但让我们暂时检查一下示例代码的设计.也许你正在使用一个不需要的通用.
你已经说过你正在使用IField接口中声明的方法,所以可能没有必要让你的IForm类通用 - 只需要存储对IField的引用,而不是通用参数'T'(已经保证)无论如何要成为IField).
例如,使用:
public interface IForm
{
IEnumerable<IField> Fields { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
代替
public interface IForm<T> where T : IField
{
IEnumerable<T> Fields { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1502 次 |
| 最近记录: |