如何添加非泛型方法来包装泛型方法

时间:2015-05-03 19:19:51

标签: c# asp.net-mvc asp.net-mvc-4 generics razor

ASP.NET MVC4 razor helper无法将类型参数传递给泛型方法。要解决这个问题,可能最好的方法是添加带签名的非泛型get方法

public static string Get(Type entityType)

如何添加此包装器,以便在此类中调用泛型Get方法。应该使用反射还是有更好的方法?

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
  public sealed class LocalizableDisplayNameAttributeI :   DisplayNameAttribute
   {

    public LocalizableDisplayNameAttributeI(string displayName) : base(displayName) { }

    public override string DisplayName
    {
        get
        {
            return global::Res.Translate(base.DisplayName);
        }
    }

    public static string Get<TEntity>()
    {
        foreach (LocalizableDisplayNameAttributeI attrib in
            typeof(TEntity).GetCustomAttributes(typeof(LocalizableDisplayNameAttributeI), true))
        {
            return attrib.DisplayName;
        }
        return typeof(TEntity).Name;
}}

3 个答案:

答案 0 :(得分:1)

反射。

return (string)(
    typeof(LocalizableDisplayNameAttributeI)
    .GetMethod("Get")
    .MakeGenericMethod(entityType)
    .Invoke(null, null)
    );

这个答案仅涉及如何调用泛型方法。但是在实际情况中,再次在非泛型版本中再次编写方法要容易得多。因为您只在上下文TEntity中使用typeof(TEntity)。因此,您只需按typeof(TEntity)搜索并替换entityType即可获得该方法的非泛型版本。

答案 1 :(得分:1)

你可以使用@JeppeStigNielsen指出的反射来做到这一点。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class LocalizableDisplayNameAttributeI : DisplayNameAttribute
{
    private static readonly MethodInfo _getMethod = typeof(LocalizableDisplayNameAttributeI)
        .GetMethods().First(x => x.IsGenericMethod && x.Name == "Get");

    public LocalizableDisplayNameAttributeI(string displayName) : base(displayName) { }

    public override string DisplayName
    {
        get
        {
            return global::Res.Translate(base.DisplayName);
        }
    }

    public static string Get(Type entityType)
    {
        return (string)_getMethod.MakeGenericMethod(entityType).Invoke(null, null);
    }

    public static string Get<TEntity>()
    {
        var attrib = typeof(TEntity)
            .GetCustomAttributes(typeof(LocalizableDisplayNameAttributeI), true)
            .FirstOrDefault() as LocalizableDisplayNameAttributeI;
        return attrib != null ? attrib.DisplayName : typeof(TEntity).Name;
    }
}

但似乎你并不真的需要这个,因为你没有使用模板参数。

您可以执行以下操作:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class LocalizableDisplayNameAttributeI : DisplayNameAttribute
{
    public LocalizableDisplayNameAttributeI(string displayName) : base(displayName) { }

    public override string DisplayName
    {
        get
        {
            return global::Res.Translate(base.DisplayName);
        }
    }

    public static string Get(Type entityType)
    {
        var attrib = entityType
            .GetCustomAttributes(typeof(LocalizableDisplayNameAttributeI), true)
            .FirstOrDefault() as LocalizableDisplayNameAttributeI;
        return attrib != null ? attrib.DisplayName : entityType.Name;
    }

    public static string Get<TEntity>()
    {
        return Get(typeof(TEntity));
    }
}

答案 2 :(得分:1)

Type转到通用调用很麻烦,但从通用调用转到Type很容易。你可以换掉你的包装订单吗?

public static string Get<TEntity>()
{
    return Get(typeof(TEntity));
}

public static string Get(Type entityType)
{
    foreach (LocalizableDisplayNameAttributeI attrib in
        entityType.GetCustomAttributes(typeof(LocalizableDisplayNameAttributeI), true))
    {
        return attrib.DisplayName;
    }
    return entityType.Name;
}