我正在尝试使用抽象的IRepository
类型来抽象我的简单Entity<T>
实体参数,以遵循DRY原理,并且不要在子类中重复Create(this)
。但是我遇到了这个错误:
CS1503参数1:无法从“实体”转换为“ T”
IRepository.cs:
public interface IRepository<T>
{
void Create(T entity);
IEnumerable<T> ReadAll();
}
Entity.cs:
public abstract class Entity<T>
{
protected IRepository<T> repository;
public void Create()
{
repository.Create(this);//Error occurs here on this
}
}
但是如果使public void Create()
抽象并在子类中实现,则一切正常:
Entity.cs
public abstract class Entity<T>
{
protected IRepository<T> repository;
public abstract void Create();//Signature changed
}
TestEntity.cs
public class TestEntity:Entity<TestEntity>
{
public override void Create()
{
repository.Create(this);
}
}
但是显然,此方法将复制并粘贴到Entity
的所有子类上。
为我的亲爱的朋友提供其他帮助:
public abstract class Base<T>
{
public abstract String GetName();
public String GetMyName()
{
return $"My Name is :{this.GetName()} Type:{this.GetType().ToString()} Is Base<T>:{this is Base<T>}";
}
}
public class Sample : Base<Sample>
{
public override string GetName()
{
return nameof(Sample);
}
}
和MessageBox.Show(new Sample().GetMyName());
的结果将是:
我的名字是:样品类型:样品是基数:真
没有任何错误。
这是另一个基于Try的朋友的答案:
public interface IRepository<T>
{
void Create(Entity<T> entity);
IEnumerable<T> ReadAll();
}
public abstract class Entity<T>
{
protected IRepository<T> repository;
public virtual void Create()
{
repository.Create(this);
}
}
public class TestEntity : Entity<TestEntity>
{
public String Name { get; set; }
}
public class Repository<T> : IRepository<T>
{
List<T> list = new List<T>();
public void Create(Entity<T> entity)
{
list.Add(this);//Error
list.Add(entity);//Also Error
}
public IEnumerable<T> ReadAll()
{
return list;
}
}
答案 0 :(得分:1)
问题是您的Entity类存储库声明,请尝试以下操作:
public abstract class Entity<T>
{
protected IRepository<Entity<T>> repository;
public void Create()
{
repository.Create(this);
}
}
答案 1 :(得分:0)
您需要在void Create(T entity);
界面中将void Create(Entity<T> entity);
更改为IRepository<T>
才能完成这项工作。
public interface IRepository<T>
{
void Create(Entity<T> entity);
IEnumerable<T> ReadAll();
}
public abstract class Entity<T>
{
public T Value;
protected IRepository<T> repository;
public void Create()
{
repository.Create(this);
}
}
public class TestEntity : Entity<TestEntity>
{
}
public class Repository<T> : IRepository<T>
{
List<T> list = new List<T>();
public void Create(Entity<T> entity)
{
list.Add(entity.Value);
}
public IEnumerable<T> ReadAll()
{
return list;
}
}
答案 2 :(得分:0)
问题
您的问题源于您的IRepository
类期望使用类型T,但是您正在将其传递给Entity<T>
而不是T。
如果您要在T用作字符串的情况下使用此类,则最终会这样:
public interface IRepository<string>
{
void Create(string entity);
IEnumerable<string> ReadAll();
}
public abstract class Entity<string>
{
protected IRepository<string> repository;
public abstract void Create();//Signature changed
}
public abstract class Entity<string>
{
protected IRepository<string> repository;
public void Create()
{
//Here the compiler is expecting the parameter to be of type string,
//but you are passing a Entity<string> instead.
//The compiler doesn't know how to cast it, so it throws an error.
repository.Create(this);
}
}
解决方案
如其他解决方案所述,您可以使字段存储库接受Entity<T>
而不是T,这将解决该问题并确实带来更多的复杂性。
另一种解决方案是像这样修改界面的“ Create”方法:
public interface IRepository<T>
{
void Create(Entity<T> entity);
IEnumerable<T> ReadAll();
}
但是,这将迫使您的界面只能与Entities类一起使用。
答案 3 :(得分:0)
也许您应该在界面方法中使用Entity<T>
而不是<T>
:
public interface IRepository<T>
{
void Create(Entity<T> entity);
IEnumerable<Entity<T>> ReadAll();
}
public abstract class Entity<T>
{
protected IRepository<T> repository;
public void Create()
{
repository.Create(this);
}
public IEnumerable<Entity<T>> ReadAll()
{
return repository.ReadAll();
}
}
答案 4 :(得分:0)
Create(this)
方法是可行的,这就是我的推断方式
public interface IEntity
{
}
public interface IEntity<T> : IEntity
where T : IEntity
{
}
public class BaseEntity<T> : IEntity
where T : IEntity, IEntity<T>
{
}
public interface IRepository<T>
where T: IEntity
{
void Create(T entity);
IEnumerable<T> ReadAll();
}
public class Entity<T> : BaseEntity<T>
where T: IEntity,
IEntity<T>,
IEquatable<Entity<T>>
{
protected IRepository<IEntity> repository;
public virtual void Create()
{
repository.Create(this);
}
public bool Equals(Entity<T> other)
{
throw new NotImplementedException();
}
}
这无疑会增加更多的复杂性,因此最好将Create(this)重构。