我喜欢将我的定义与我的实现分开。我有一个接口实体:
public interface Entity<E> where E : Entity<E>
{
EntityId EntityId { get; }
bool ReadOnly { get; }
void FailIfReadOnly();
E Copy();
}
E是实际的实体类型,例如Customer:
public interface Customer : Entity<Customer>
{
}
我遇到的问题是FailIfReadOnly()的实现:如果ReadOnly == true,则抛出EntityIsReadOnlyException。
public class EntityIsReadOnlyException<E> where E : Entity<E>
{
public EntityIsReadOnlyException(E entity)
: base(string.Format("Entity {0} is read only", entity.EntityId))
{
}
}
public class EntityImpl<E> : Entity<E> where E : Entity<E>
{
public EntityImpl(E other)
{
}
public bool ReadOnly
{
get;
protected set;
}
public void FailIfReadOnly()
{
if (! ReadOnly) throw new EntityIsReadOnlyException<E>(this);
}
}
throw new EntityIsReadOnlyException<E>(this);
导致编译错误:
'EntityIsReadOnlyException.EntityIsReadOnlyException(E)'的最佳重载方法匹配有一些无效的参数
参数'1':无法从'EntityImpl'转换为'E'
我能做到:
EntityIsReadOnlyExcetion<Customer> exc = new EntityIsReadOnlyException<Customer>(customerImpl);
甚至:
Entity<E> entity = new EntityImpl<E>(this);
但不是:
EntityIsReadOnlyException<E> exc = new EntityIsReadOnlyException<E>(this);
在这两种情况下,E仅限于实体的子类。我的问题是,为什么我会收到此编译错误?这可能非常简单。
答案 0 :(得分:4)
首先,您的异常类不是从Exception派生的:
public class EntityIsReadOnlyException<E> : Exception where E : Entity<E>
然后请注意,您的异常构造函数不会将Entity<E>
作为参数,而是使用E.
方法1:将构造函数更改为Entity<E>
:
public EntityIsReadOnlyException(Entity<E> entity)
方法2:将other
传递给您的例外:
E other;
public EntityImpl(E other)
{
this.other = other;
}
...
if (ReadOnly) throw new EntityIsReadOnlyException<E>(other);
非工作方法:尝试将其转换为E:
if (ReadOnly) throw new EntityIsReadOnlyException<E>((E)(Entity<E>)other);
这是编译,但在运行时失败,因为您的实现对象与参数E的类型不同,并且无法强制转换为它。
另一个小问题:你的if (!ReadOnly)
检查是错误的。它应该是if (ReadOnly)
。
答案 1 :(得分:0)
嗯......
错误信息非常明确:您无法将EntityImpl转换为E ...只是因为实体不是从E派生而且还没有实现转换运算符......
您可以使用Mark的方式或将Entity接口重写为具有隐式运算符E(实体实体)的抽象类和具有至少一个参数E实例的构造函数。所以你派生的所有类都能够实现这一点。