@cicatrix
было бы большой ошибкой думать

Как реализовать Generic объект из интерфейса?

Есть класс:
public class Repository<T> where T : IDbUpdatable<T>
 {
 }


Есть интерфейс:
public interface IDbUpdatable<T>
    {
        Repository<T> GetRepository();
        int Update();
        int Delete();
    }


Собственно, идея такая - Repository должен работать с любым типом, реализующим IDbUpdatable. Соответственно, класс, реализующий IDbUpdatable должен возвращать ссылку на свой Repository через GetRepository

The type 'T' cannot be used as type parameter 'T' in the generic type or method 'Repository'. There is no boxing conversion or type parameter conversion from 'T' to '.IDbUpdatable'.

Не совсем понял, что компилятору не нравится.
  • Вопрос задан
  • 385 просмотров
Решения вопроса 2
NightmareZz
@NightmareZz
Нищий разработчик из Симферополя
public class Repository<T> where T : IDbUpdatable<T>
{
}

public interface IDbUpdatable<T> where T : IDbUpdatable<T>
{
    Repository<T> GetRepository();
    int Update();
    int Delete();
}
Ответ написан
@lvv85
The type 'T' cannot be used as type parameter 'T' in the generic type or method 'Repository'. There is no boxing conversion or type parameter conversion from 'T' to '.IDbUpdatable'.


Тип 'T' должен быть IDbUpdatable<T>, тогда данной ошибки не будет.

public interface IDbUpdatable<T> where T : IDbUpdatable<T>
    {
        Repository<T> GetRepository();
        int Update();
        int Delete();
    }
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@dmitryKovalskiy
программист средней руки
Я в интерфейсе вижу какую-то зацикленную ерунду, которую не получается в голове разрулить.
Вы пишете репозиторий с типом T где Т реализует интерфейс IDbUpdatable при том что сам интерфейс - типизирован от Т(т.е. фактически Repository<IDbUpdatable<IDbUpdatable<...<...<>>>>и т.д.). Он как-то сам в себя куда-то проваливается и как это потом разрулить мне не понятно.
Ответ написан
Комментировать
@kttotto
пофиг на чем писать
В Вашем варианте:
public interface IRepository<T>
	{
		T Create();
		T Read();
		T Update();
		T Delete();
	}

	public class Repository<T> where T : IRepository<T>
	{
		public static Repository<T> CreateRepository()
		{
			return new Repository<T>();
		}
	}

Но не думаю, что это верный подход. Потому, что в этом случае, каждая POKO модель должна будет наследоваться от IRepository. Архитектурно не правильно, выглядеть будет следующим образом
class Program
{
    static void Main(string[] args)
    {
		var repository = Repository<Comment>.CreateRepository();

        Console.ReadKey();
    }
}

public class Comment : IRepository<Comment>
{
	public int Id { get; set; }
	public string Name { get; set; }

	public Comment Create()
	{
		return this;
	}

	public Comment Read()
	{
		return this;
	}

	public Comment Update()
	{
		return this;
	}

	public Comment Delete()
	{
		return this;
	}
}


Если хотите дженерик репозиторий, могу предложить свой вариант, который я использовал в некоторых своих проектах. При желании адаптируйте его под свои нужды.
Example
public interface IRepository where T : class
{
IEnumerable GetAll();
T GetById(int id);
T Create(T model);
T Update(T model);
T Delete(int id);
}

public class EFRepository : IRepository where T : class
{
protected readonly DbContext _dbContext;

public EFRepository(DbContext dbContext)
{
_dbContext = dbContext;
}

public virtual IEnumerable GetAll()
{
return _dbContext.Set();
}

public virtual T GetById(int id)
{
return _dbContext.Set().Find(id);
}

public virtual T Create(T model)
{
var entity = _dbContext.Set().Add(model);
return entity;
}

public virtual T Update(T model)
{
_dbContext.Entry(model);
return model;
}

public virtual T Delete(int id)
{
var model = _dbContext.Set().Find(id);
var entity = _dbContext.Set().Remove(model);
return entity;
}
}

public interface IPostRepository : IRepository
{
IEnumerable GetByUserId(string id);
}

public class EFPostRepository : EFRepository, IPostRepository
{
public EFPostRepository(DbContext dbContext) : base(dbContext)
{
}

public IEnumerable GetByUserId(string id)
{
return _dbContext
.Posts
.Where(x => x.UserId == id);
}
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы