由于签名不同(使用泛型),C# 无法实现接口方法
C# cant implement interface method because of different signatures (using generics)
我有一个基本的 class 和两个嵌套的 class。其中一个嵌套的 class 正在实现一个接口,其中我有一个带有 return 类型的嵌套对象的方法签名。
这是我得到的:
Class一个
using System;
namespace Nested
{
class A
{
public class Item
{
//Implementation
}
class B : IInterface
{
//
public Item Get()
{
throw new NotImplementedException();
}
}
}
}
ClassA
的接口
namespace Nested
{
internal interface IInterface
{
A.Item Get();
}
}
与泛型相同
Class B
using System;
namespace Nested
{
class A<T>
{
public class Item<T>
{
//Implementation
}
class B<T> : IInterface<T>
{
//
public Item<T> Get()
{
throw new NotImplementedException();
}
}
}
}
classB
的接口
namespace Nested
{
internal interface IInterface<T>
{
A<T>.Item<T> Get();
}
}
第一个代码没有使用泛型,但运行良好。与此相比,泛型示例给出了以下错误:
Class1.cs(13,22): error CS0738: 'A<T>.B<T>' does not implement interface member 'IInterface<T>.Get()'. 'A<T>.B<T>.Get()' cannot implement 'IInterface<T>.Get()' because it does not have the matching return type of 'A<T>.Item<T>
为什么在接口使用A<T>.Item<T> Get();
和classpublic Item<T> Get()
时说return类型不同?有什么想法吗?
编辑:停止将错误代码格式化为块引用,因为片段正在丢失。那不是我收到的正确消息。
因为 A.Item
和 A.Item<T>
是不同的类型,您的接口契约是 return 来自 Get
方法的项目而不是 Item<T>
。
万一你在定义泛型 classes 时,你也需要泛型接口,非泛型接口方法契约不适用于方法 return 泛型类型,所以可能您还需要为通用类型添加一个通用接口:
public interface IInterface<T>
{
A<T>.Item<T> Get<T>();
}
更新:
您的接口合约指定 Get
到 return A<T>.Item<T>
:
A<T>.Item<T> Get();
而您的实现类型 B<T>
仅将 return 类型指定为 Item<T>
:
public Item<T> Get()
{
throw new NotImplementedException();
}
由于编译器不允许
由于接口指定return类型为A<T>.Item<T>
所以应该是class中Get
方法的return类型 B<T>
也是,否则它也会抱怨 A<T>.Item<T>
和 Item<T>
当然是不同的,所以像下面这样更改 B<T>
修复了错误:
class B<T> : IInterface<T>
{
//
public A<T>.Item<T> Get<T>()
{
throw new NotImplementedException();
}
}
你可以看下面的演示fiddle:
当你有
class A<T>
{
class B<T> { }
}
你应该(根据你的设置)得到 compiler warning CS0693:
Type parameter 'T' has the same name as the type parameter from outer type 'A'
这是因为泛型 class 中的嵌套 class 将采用外部 class 的类型参数,例如
class A<T>
{
class B
{
public T Value { get; set; }
{
}
完全有效 - B
获得与其外部 class A
相同的类型参数,因此可以像定义为非嵌套 class 一样使用它] B<T>
.
您的代码等同于
class A<T>
{
class B<U> { }
}
或者说,A
和B
中的类型参数不一样,你没希望满足接口。
如果你忽略那个警告(不推荐)可以做一些像这样的可怕的事情:
#pragma warning disable 0693
public class A<T> where T : struct
{
public class B<T> where T : class
{
}
}
#pragma warning restore 0693
如果 A<T>
和 B<T>
中的 T
是同一类型参数(一个类型不能同时是 struct
和一个 class
),但反而非常混乱。
如果在 Visual Studio 中查看,IntelliSense 将显示:
所以 A<T>
范围内的 T
与 [=18= 范围内的 T
不同 ] - 后者 隐藏 前者。
事实上,没有什么能阻止你
var ab = new A<double>.B<Object>();
即使类型参数的 name 对于 A<T>
和 B<T>
都是 T
。因此编译器警告。
我想你想要的是这个:
class A<T>
{
public class Item
{
//Implementation
}
class B : IInterface<T>
{
public Item Get()
{
throw new NotImplementedException();
}
}
}
internal interface IInterface<T>
{
A<T>.Item Get();
}
在 https://dotnetfiddle.net/nBFVLw 查看此答案的 fiddle。
如果您不熟悉嵌套泛型类型的使用,它们可能会违反直觉。
我有一个基本的 class 和两个嵌套的 class。其中一个嵌套的 class 正在实现一个接口,其中我有一个带有 return 类型的嵌套对象的方法签名。
这是我得到的:
Class一个
using System;
namespace Nested
{
class A
{
public class Item
{
//Implementation
}
class B : IInterface
{
//
public Item Get()
{
throw new NotImplementedException();
}
}
}
}
ClassA
的接口namespace Nested
{
internal interface IInterface
{
A.Item Get();
}
}
与泛型相同
Class B
using System;
namespace Nested
{
class A<T>
{
public class Item<T>
{
//Implementation
}
class B<T> : IInterface<T>
{
//
public Item<T> Get()
{
throw new NotImplementedException();
}
}
}
}
classB
的接口namespace Nested
{
internal interface IInterface<T>
{
A<T>.Item<T> Get();
}
}
第一个代码没有使用泛型,但运行良好。与此相比,泛型示例给出了以下错误:
Class1.cs(13,22): error CS0738: 'A<T>.B<T>' does not implement interface member 'IInterface<T>.Get()'. 'A<T>.B<T>.Get()' cannot implement 'IInterface<T>.Get()' because it does not have the matching return type of 'A<T>.Item<T>
为什么在接口使用A<T>.Item<T> Get();
和classpublic Item<T> Get()
时说return类型不同?有什么想法吗?
编辑:停止将错误代码格式化为块引用,因为片段正在丢失。那不是我收到的正确消息。
因为 A.Item
和 A.Item<T>
是不同的类型,您的接口契约是 return 来自 Get
方法的项目而不是 Item<T>
。
万一你在定义泛型 classes 时,你也需要泛型接口,非泛型接口方法契约不适用于方法 return 泛型类型,所以可能您还需要为通用类型添加一个通用接口:
public interface IInterface<T>
{
A<T>.Item<T> Get<T>();
}
更新:
您的接口合约指定 Get
到 return A<T>.Item<T>
:
A<T>.Item<T> Get();
而您的实现类型 B<T>
仅将 return 类型指定为 Item<T>
:
public Item<T> Get()
{
throw new NotImplementedException();
}
由于编译器不允许
由于接口指定return类型为A<T>.Item<T>
所以应该是class中Get
方法的return类型 B<T>
也是,否则它也会抱怨 A<T>.Item<T>
和 Item<T>
当然是不同的,所以像下面这样更改 B<T>
修复了错误:
class B<T> : IInterface<T>
{
//
public A<T>.Item<T> Get<T>()
{
throw new NotImplementedException();
}
}
你可以看下面的演示fiddle:
当你有
class A<T>
{
class B<T> { }
}
你应该(根据你的设置)得到 compiler warning CS0693:
Type parameter 'T' has the same name as the type parameter from outer type 'A'
这是因为泛型 class 中的嵌套 class 将采用外部 class 的类型参数,例如
class A<T>
{
class B
{
public T Value { get; set; }
{
}
完全有效 - B
获得与其外部 class A
相同的类型参数,因此可以像定义为非嵌套 class 一样使用它] B<T>
.
您的代码等同于
class A<T>
{
class B<U> { }
}
或者说,A
和B
中的类型参数不一样,你没希望满足接口。
如果你忽略那个警告(不推荐)可以做一些像这样的可怕的事情:
#pragma warning disable 0693
public class A<T> where T : struct
{
public class B<T> where T : class
{
}
}
#pragma warning restore 0693
如果 A<T>
和 B<T>
中的 T
是同一类型参数(一个类型不能同时是 struct
和一个 class
),但反而非常混乱。
如果在 Visual Studio 中查看,IntelliSense 将显示:
所以 A<T>
范围内的 T
与 [=18= 范围内的 T
不同 ] - 后者 隐藏 前者。
事实上,没有什么能阻止你
var ab = new A<double>.B<Object>();
即使类型参数的 name 对于 A<T>
和 B<T>
都是 T
。因此编译器警告。
我想你想要的是这个:
class A<T>
{
public class Item
{
//Implementation
}
class B : IInterface<T>
{
public Item Get()
{
throw new NotImplementedException();
}
}
}
internal interface IInterface<T>
{
A<T>.Item Get();
}
在 https://dotnetfiddle.net/nBFVLw 查看此答案的 fiddle。
如果您不熟悉嵌套泛型类型的使用,它们可能会违反直觉。