在 C# 中实现接口的泛型方法时出现奇怪的错误。这里到底出了什么问题?
I am getting weird errors while implementing a generic method of an interface in C#. What exactly is going wrong here?
public interface IGet<T>
{
T Get<K>(K id);
}
public interface IDemoRepository : IGet<Dto.Message>
{
}
public class DemoRepository : IDemoRepository
{
public Dto.Message Get<string>(string messageId)
{
using (var db = new AppDbContext())
{
return db.Messages
.FirstOrDefault(f => f.MessageId.ToLower() == messageId.ToLower());
}
}
}
以下是错误列表中的错误。
Severity Code Description
Error CS1001 Identifier expected
Error CS1003 Syntax error, '>' expected
Error CS1003 Syntax error, '(' expected
Error CS1001 Identifier expected
Error CS1003 Syntax error, ',' expected
Error CS1003 Syntax error, ',' expected
Error CS8124 Tuple must contain at least two elements.
Error CS1001 Identifier expected
Error CS1026 ) expected
Error CS0535 'DemoRepository' does not implement interface member 'IGet<Dto.Message>.Get<K>(K)'
Error CS0103 The name 'messageId' does not exist in the current context
具有成功和失败场景的 .NET fiddle
here
接口指定 Get
应采用通用参数,但您正试图使用 string
参数来定义它。
要么改变你的 DemoRepository
使 Get
通用(这看起来不适合你的情况,因为你想使用 .ToLower
)。
或者将您的 Get
更改为非通用的。
编译器给出这么多错误的原因是因为它期望在 <>
中有一个标识符,但你在那里放了一个关键字 (string
)。编译器因此变得混乱,解析变得非常错误。这也是为什么使用 Guid
时错误会少得多的原因,因为 Guid
是一个标识符。但是将 string
替换为 Guid
也不符合您的预期。
您似乎希望 DemoRepository
仅在非常具体的情况下实施 IDemoRepository
,即当 K
为 string
.
请注意,实现 IDemoRepository
的要求是它应该具有 generic Get
方法,能够采用 any 输入 K
,然后 returns 一个 Dto.Message
。这是什么意思:
public interface IGet<T>
{
T Get<K>(K id);
}
public interface IDemoRepository : IGet<Dto.Message>
{
}
我想这不是您真正想要 IDemoRepository
要求的?如果你只希望它需要一个非通用的 Get
方法。它采用 specific 类型 K
,可以由实施者选择,然后你可以这样做:
// I moved the generic parameter K from the method to the interface
public interface IGet<T, K>
{
T Get(K id);
}
public interface IDemoRepository<K> : IGet<Dto.Message, K>
{
}
// here the implementer chose string as K
public class DemoRepository : IDemoRepository<string>
{
public Dto.Message Get(string messageId)
{
...
}
}
public interface IGet<T>
{
T Get<K>(K id);
}
public interface IDemoRepository : IGet<Dto.Message>
{
}
public class DemoRepository : IDemoRepository
{
public Dto.Message Get<string>(string messageId)
{
using (var db = new AppDbContext())
{
return db.Messages
.FirstOrDefault(f => f.MessageId.ToLower() == messageId.ToLower());
}
}
}
以下是错误列表中的错误。
Severity Code Description
Error CS1001 Identifier expected
Error CS1003 Syntax error, '>' expected
Error CS1003 Syntax error, '(' expected
Error CS1001 Identifier expected
Error CS1003 Syntax error, ',' expected
Error CS1003 Syntax error, ',' expected
Error CS8124 Tuple must contain at least two elements.
Error CS1001 Identifier expected
Error CS1026 ) expected
Error CS0535 'DemoRepository' does not implement interface member 'IGet<Dto.Message>.Get<K>(K)'
Error CS0103 The name 'messageId' does not exist in the current context
具有成功和失败场景的 .NET fiddle here
接口指定 Get
应采用通用参数,但您正试图使用 string
参数来定义它。
要么改变你的 DemoRepository
使 Get
通用(这看起来不适合你的情况,因为你想使用 .ToLower
)。
或者将您的 Get
更改为非通用的。
编译器给出这么多错误的原因是因为它期望在 <>
中有一个标识符,但你在那里放了一个关键字 (string
)。编译器因此变得混乱,解析变得非常错误。这也是为什么使用 Guid
时错误会少得多的原因,因为 Guid
是一个标识符。但是将 string
替换为 Guid
也不符合您的预期。
您似乎希望 DemoRepository
仅在非常具体的情况下实施 IDemoRepository
,即当 K
为 string
.
请注意,实现 IDemoRepository
的要求是它应该具有 generic Get
方法,能够采用 any 输入 K
,然后 returns 一个 Dto.Message
。这是什么意思:
public interface IGet<T>
{
T Get<K>(K id);
}
public interface IDemoRepository : IGet<Dto.Message>
{
}
我想这不是您真正想要 IDemoRepository
要求的?如果你只希望它需要一个非通用的 Get
方法。它采用 specific 类型 K
,可以由实施者选择,然后你可以这样做:
// I moved the generic parameter K from the method to the interface
public interface IGet<T, K>
{
T Get(K id);
}
public interface IDemoRepository<K> : IGet<Dto.Message, K>
{
}
// here the implementer chose string as K
public class DemoRepository : IDemoRepository<string>
{
public Dto.Message Get(string messageId)
{
...
}
}