我在将实体转换为接口以在静态方法中使用时遇到问题。我收到的错误是 InvalidCastException。我需要执行此转换,因为我有一个需要采用特定接口定义的静态方法。我认为(虽然我没有尝试过)使用抽象类而不是接口可能会起作用,但 C# 不支持从抽象类继承,并且我的实体已经从一个抽象类继承。
我的模型相当简单。我有一个实体对象 - MemberStatus - 它具有 Id、Name 和 DisplayOrder。它继承自Entity抽象类(继承自IIdentABLEEntity)并实现INamedEntity、IOrderedEntity接口。这些抽象类或接口中的每一个都只包含一个属性(Id、Name 和 DisplayOrder)。
这是我的域项目中的代码:
public abstract class Entity : IIdentifiableEntity
{
public int Id { get; set; }
}
public interface INamedEntity
{
string Name { get; set; }
}
public interface IOrderedEntity
{
float DisplayOrder { get; set; }
}
public class MemberStatus : Entity, INamedEntity, IOrderedEntity
{
public string Name { get; set; }
public float DisplayOrder { get; set; }
}
public interface IRepository<TEntity>
{
TEntity FindById(int id);
bool InsertOrUpdate(TEntity entity);
//... More methods here
}
这是我的静态方法(我希望能够将其用于任何 IOrderedEntity):
public static void MoveDisplayOrder(IRepository<IOrderedEntity> repository, int id, bool moveUp)
{
var currentStatus = repository.FindById(id);
//...do reordering work
repository.InsertOrUpdate(currentStatus);
}
在我的 MVC 控制器(在我的 Web 项目中)中,我有以下内容:
public class AdminController : Controller
{
private readonly IRepository<MemberStatus> _memberStatusRepository;
public AdminController(IRepository<MemberStatus> memberStatusRepository)
{
_memberStatusRepository = memberStatusRepository;
}
public ActionResult StatusMoveDisplayOrder(int id, bool moveUp)
{
// Code fails on the following line...
MoveDisplayOrder((IRepository<IOrderedEntity>) _memberStatusRepository, id, moveUp);
return RedirectToAction("Index");
}
// Rest of controller code here...
}
代码失败(在当控制器调用 StatusMoveDisplayOrder 并依次尝试调用静态 MoveDisplayOrder
时,它编译得很好。所有这些代码都工作得很好,直到我将 MoveDisplayOrder 设为静态并将第一个参数从 IRepository
更改为 IRepository
。我再次进行了更改,以便可以在任何具有 DisplayOrder 属性(实现 IOrderedEntity)的实体上调用此方法。我做错了什么?
仅供参考 - 我正在使用 ninject,以防万一我需要调整其中的内容。
I am having an issue casting an entity to a interface to use within a static method. The error I get is a InvalidCastException. I need to perform this cast because I have a static method that needs to take an specific interface definition. I think (though I haven't tried) that using an abstract class as opposed to an interface might work, but C# doesn't support inheritance from abstract classes and my entity already inherits from one abstract class.
My model is fairly simple. I have one entity object - MemberStatus - that has an Id, Name and DisplayOrder. It inherits from an Entity abstract class (which inherits from IIdentifiableEntity) and implements the INamedEntity, IOrderedEntity interfaces. Each of these abstract classes or interfaces contains just one property (Id, Name and DisplayOrder).
Here's my code within my domain project:
public abstract class Entity : IIdentifiableEntity
{
public int Id { get; set; }
}
public interface INamedEntity
{
string Name { get; set; }
}
public interface IOrderedEntity
{
float DisplayOrder { get; set; }
}
public class MemberStatus : Entity, INamedEntity, IOrderedEntity
{
public string Name { get; set; }
public float DisplayOrder { get; set; }
}
public interface IRepository<TEntity>
{
TEntity FindById(int id);
bool InsertOrUpdate(TEntity entity);
//... More methods here
}
Here is my static method (which I want to be able to be use for any IOrderedEntity):
public static void MoveDisplayOrder(IRepository<IOrderedEntity> repository, int id, bool moveUp)
{
var currentStatus = repository.FindById(id);
//...do reordering work
repository.InsertOrUpdate(currentStatus);
}
Within my MVC controller (in my web project), I then have the following:
public class AdminController : Controller
{
private readonly IRepository<MemberStatus> _memberStatusRepository;
public AdminController(IRepository<MemberStatus> memberStatusRepository)
{
_memberStatusRepository = memberStatusRepository;
}
public ActionResult StatusMoveDisplayOrder(int id, bool moveUp)
{
// Code fails on the following line...
MoveDisplayOrder((IRepository<IOrderedEntity>) _memberStatusRepository, id, moveUp);
return RedirectToAction("Index");
}
// Rest of controller code here...
}
The code fails (at run time... it compiles fine) when the controller calls StatusMoveDisplayOrder and it in turn tries to call the static MoveDisplayOrder
. All this code was working perfectly until I made the MoveDisplayOrder static and changed the first parameter from IRepository<MemberStatus>
to IRepository<IOrderedEntity>
. Again, I made that change so that I can call this method on any entity that has a DisplayOrder property (implements IOrderedEntity). What am I doing wrong?
FYI - I am using ninject, in case there is something in there that I need to adjust.
发布评论
评论(1)
IRepository>即使 MemberStatus 实现了 IOrderedEntity,也不是
IRepository
。如果您确实希望能够进行类型转换,则需要使 IRepository 成为这样的协变通用接口。http://msdn.microsoft.com/en-us/library/dd997386.aspx
但这是不可能的,因为 IRepository 的方法无法将 TEntity 作为参数。您可以更改静态方法,而不是强制转换。
IRepository<MemberStatus
> is not anIRepository<IOrderedEntity>
even though MemberStatus implements IOrderedEntity. You need to make IRepository a covariant generic interface like this if you really wanted to be able to do the type conversion.http://msdn.microsoft.com/en-us/library/dd997386.aspx
This isn't possible as written though because IRepository's methods wouldn't be able to take the TEntity as a parameter. Instead of casting you can change your static method..