我们假设我有:
Get<T>
IEntity
,IValue
Entity
- &gt; IEntity
,Value
- &gt; IValue
等。 =&GT;有没有办法让Get<T>
方法只允许接口作为泛型类型?
Get<IEntity>(42); //Allowed
Get<Entity>(42); //Compiler error
我目前的解决方案如下:
Get<T>
的通用方法where T: IPersistable
(以防止大多数类型作为参数传递)IPersistable
该功能主动检查类型:
public T Get<T>(long id) where T : IPersistable
{
if (typeof (T) == typeof (IEntity))
return (T) EntityDao.Get(id);
if (typeof (T) == typeof (IValue))
return (T) ValueDao.Get(id);
//...
throw new TechnicalException("Type not supported");
}
=&GT;问题是:
IPersistable
进入,但不是真的&lt; - 真的让我感到困惑:( 编辑:我正在考虑这样的限制,以避免我的班级人口过剩。
我在那个类中有类似8或9个泛型方法的东西,它们都以这种方式工作。直观的做法是@DanielHilgarth建议每种类型只有1种方法。目前可以使用4种或5种类型调用这些方法。但是,这仍然意味着该课程中有32-40种方法。
如果可能,我想避免这种情况。
Edit2 :防止“真实”类被调用的需要来自协方差/逆变问题。 EntityDao和ValueDao Get<T>
方法返回IEntity
和IValue
个对象。当我在GetAll<T>
方法中调用集合时,当我查询单个对象时,什么工作正常,因为我无法在IEnumerable<IValue>
中强制转换IEnumerable<Value>
。
我刚从@JonSkeets注意到关于列表的转换this answer。这可能是一种解决方法......
答案 0 :(得分:5)
您应该只创建专用方法。带有if
的示例代码显示您当前的方法不做一件事。它有多个。
请继续:
GetEntity(42);
GetValue(13);
public IEntity GetEntity(long id)
{
return EntityDao.Get(id);
}
public IValue GetValue(long id)
{
return ValueDao.Get(id);
}
在所有图层上都更加清晰:
GetEntity
与Get<IEntity>
如果这会导致您的服务上有太多类似的方法,那么就应该打破新的类,例如一个用于Entity
,另一个用于Value
。
然后,您可以提供返回新类的服务属性。这与我在实施my query objects时所做的相同。它可能如下所示:service.Values.Get(13)
和service.Entities.Get(42)
答案 1 :(得分:1)
这可能是另一种选择:
abstract class Persistable<T>
{
protected static Func<long, T> mapFunction;
public static T Get(long id)
{
return mapFunction(id);
}
}
class Entity : Persistable<Entity>
{
public static Entity()
{
Persistable<Entity>.mapFunction = input => EntityDao.Get(input);
}
}
class Value : Persistable<Value>
{
public static Value()
{
Persistable<Value>.mapFunction = input => ValueDao.Get(input);
}
}
您的Get
方法将是这样的:
public T Get<T>(long id) // maybe you restrict the T to something
{
Persistable<T>.Get(id);
}