泛型的设计问题

本文关键字:问题 泛型 | 更新日期: 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的类型是未知的。我如何验证Tintstring,然后成功地将参数传递给合适的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,因此它很容易转换为intstring或其他类型。

答案是你想要的泛型类并不是最好的方法:您应该创建一个具有两个重载的方法,一个用于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
}