将实体强制转换为接口以在静态方法中使用时出现InvalidCastException
本文关键字:InvalidCastException 静态方法 实体 转换 接口 | 更新日期: 2023-09-27 18:19:50
我在将实体转换为要在静态方法中使用的接口时遇到问题。我得到的错误是一个InvalidCastException。我需要执行这个强制转换,因为我有一个静态方法,需要采用特定的接口定义。我认为(尽管我还没有尝试过)使用抽象类而不是接口可能会起作用,但C#不支持从抽象类继承,我的实体已经从一个抽象类继承了。
我的模型相当简单。我有一个实体对象MemberStatus,它有一个Id、Name和DisplayOrder。它继承自Entity抽象类(继承自IIidentifiebleEntity),并实现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<MemberStatus>
更改为IRepository<IOrderedEntity>
。再次,我进行了更改,以便可以在任何具有DisplayOrder属性(实现IOrderedEntity)的实体上调用此方法。我做错了什么?
仅供参考-我正在使用ninject,以防其中有需要调整的内容。
IRepository<MemberStatus
>不是IRepository<IOrderedEntity>
,即使MemberStatus实现了IOrderedEntity。如果您真的想进行类型转换,那么您需要将IRepository设置为这样的协变泛型接口。
interface IRepository<out T>
{
}
http://msdn.microsoft.com/en-us/library/dd997386.aspx
但这在编写时是不可能的,因为IRepository的方法不能将TEntity作为参数。你可以改变你的静态方法,而不是铸造。。
public static void MoveDisplayOrder<T>(IRepository<T> repository, int id,
bool moveUp) where T : IOrderedEntity
{
var currentStatus = repository.FindById(id);
//...do reordering work
repository.InsertOrUpdate(currentStatus);
}