Generics的设计问题

时间:2013-06-21 08:49:30

标签: c# generics

我有一个有两个公共方法的类:

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的类型未知。如何验证Tint还是string,然后成功将参数传递给合适的GetEntity()方法?

6 个答案:

答案 0 :(得分:3)

我看不出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);
    }
}

答案 1 :(得分:1)

只需使用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
    }
}

答案 2 :(得分:0)

由于您已经知道允许的类型,并且它们不是泛型,为什么要尝试使用泛型来解决问题?只需创建两个使用正确类型调用GetEntity的方法。

您可以随时检查T的类型,并在将其传递给GetEntity时将其转换为正确的类型:

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
}

答案 3 :(得分:0)

假设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运算符

答案 4 :(得分:0)

您可以尝试以下代码:

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或其他类型。

答案 5 :(得分:0)

答案是你想要的通用类不是最好的做法: 您应该创建一个具有两个重载的方法,一个用于int,一个用于字符串:

class EntityHandler
{
    public IEntity RetrieveEntity (int userParam) { }
    public IEntity RetrieveEntity (string userParam) { }

}

其他方法,您检查传递的对象的类型倾向于在编译时传递除int或字符串以外的类型,使API不直观。

在传递复杂对象类型而不是整数和字符串的情况下,可以使它们实现基本接口并在泛型上使用where constraint。在这种情况下,你不能。

也许你真正追求的是:

class EntityHandler<TEntity> where TEntity : IEntity
{
    public TEntity RetrieveEntity (int userParam) { }
    public TEntity RetrieveEntity (string userParam) { }

}