Я получаю странные ошибки при реализации универсального метода c интерфейса в C#. Что именно здесь не так? - PullRequest
4 голосов
/ 13 июля 2020
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  

A. NET сценарии успеха и неудачи здесь

Ответы [ 2 ]

4 голосов
/ 13 июля 2020

Причина, по которой компилятор выдал так много ошибок, состоит в том, что он ожидал идентификатор в <>, но вы помещаете туда ключевое слово (string). В результате компилятор запутался, и разбор был очень неправильным. По этой же причине количество ошибок меньше, если вы используете Guid, потому что Guid - это идентификатор. Но замена string на Guid тоже не дает того, чего вы ожидаете.

Кажется, вы хотите, чтобы DemoRepository реализовал IDemoRepository только в очень конкретном случае c, т.е. когда K is string.

Обратите внимание, что требование для реализации IDemoRepository состоит в том, что он должен иметь метод generi c Get, способный принимать любые введите K и вернет Dto.Message. Вот что означает:

public interface IGet<T>
{
    T Get<K>(K id);
}

public interface IDemoRepository : IGet<Dto.Message>
{

}

Я полагаю, это не то, что вы действительно хотите, чтобы IDemoRepository требовал? Если вы хотите, чтобы он требовал необщего метода c Get. который принимает спецификацию c тип 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)
    {
        ...
    }
}
0 голосов
/ 13 июля 2020

Интерфейс указывает, что Get должен принимать общий параметр c, но вы пытаетесь определить его с помощью параметра string.

Либо измените свой DemoRepository на Get generi c (что не похоже, что это сработает в вашем случае, так как вы хотите использовать .ToLower).

Или измените свой Get на non-generi c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...