泛型的设计问题
本文关键字:问题 泛型 | 更新日期: 2023-09-27 18:19:15
我有一个有两个公共方法的类:
class FirstClass
{
public IEntity GetEntity(string byUserName);
public IEntity GetEntity(int byUserId);
}
我想用一个泛型类包装这些方法,看起来像这样:
class EntityHandler<T>
{
public IEntity RetrieveEntity (T userParam)
{
return firstClass.GetEntity(userParam)
}
}
当然这是行不通的,因为此时userParam
的类型是未知的。我如何验证T
是int
或string
,然后成功地将参数传递给合适的GetEntity()
方法?
我看不到EntityHandler
是通用的任何要求
class EntityHandler
{
FirstClass firstClass = new FirstClass();
public IEntity RetrieveEntity(int userParam)
{
return firstClass.GetEntity(userParam);
}
public IEntity RetrieveEntity(string userParam)
{
return firstClass.GetEntity(userParam);
}
}
使用is
class EntityHandler<T>
{
public IEntity RetrieveEntity (T userParam)
{
if(userParam is int)
return firstClass.GetEntity((int)(object)userParam)
else if(userParam is string)
return firstClass.GetEntity((string)(object)userParam)
else
// add your code here
}
}
假设使用java,您可以使用instanceof来确定userParam变量的类型:
if(userParam instanceof String){
String param = (String) userParam;
//yay string
} else if (userparam instanceof Integer) {
Integer param = (Integer) userParam;
//yay int
}
c#有类似的is
操作符
您可以尝试以下代码:
public IEntity RetrieveEntity(T userParam)
{
FirstClass firstClass = new FirstClass();
if (userParam is string)
return firstClass.GetEntity((string)(object)userParam);
else if (userParam is int)
return firstClass.GetEntity((int)(object)userParam);
else
return null; // or new IEntity();
}
userParam
已被类型转换为object
,因此它很容易转换为int
或string
或其他类型。
答案是你想要的泛型类并不是最好的方法:您应该创建一个具有两个重载的方法,一个用于int,一个用于string:
class EntityHandler
{
public IEntity RetrieveEntity (int userParam) { }
public IEntity RetrieveEntity (string userParam) { }
}
检查传递对象类型的其他方法容易在编译时传递int或string以外的类型,使API不直观。
在传递复杂对象类型(而不是int和string)的情况下,可以让它们实现基接口,并在泛型上使用where约束。在这种情况下,你不能。
也许你真正想要的是:
class EntityHandler<TEntity> where TEntity : IEntity
{
public TEntity RetrieveEntity (int userParam) { }
public TEntity RetrieveEntity (string userParam) { }
}
既然您已经知道了允许的类型,而且它们不是泛型,为什么还要尝试用泛型来解决问题呢?只需创建两个方法,用正确的类型调用GetEntity。
另一种方法是在传递给GetEntity时检查T的类型并将其强制转换为正确的类型:
var typeOfT = userParam.getType();
if (typeOfT == typeof(string))
{
return firstClass.GetEntity((string) userParam); //might have to do 'userParam as string' (im duck typing)
}
else if (typeOf(T) == typeof(int))
{
// call other GetEntity
}
else
{
//throw
}