找到你要的答案

Q:How to add non generic method to wrap generic method

Q:如何将非泛型方法添加到泛型方法中

ASP.NET MVC4 razor helper cannot pass type parameters to generic methods. To fix this, probably best way is to add non-generic get method with signature

public static string Get(Type entityType)

How to add this wrapper so it calls generic Get method in this class. Should reflection used or is there better way?

 [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;
}}

ASP.NET剃须刀的帮手不能通过MVC4类型参数的泛型方法。要解决这个问题,最好的方法是添加非泛型获取方法与签名

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;
}}
answer1: 回答1:

You can do that using reflection as @JeppeStigNielsen already indicated.

[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;
    }
}

But it seems you don't really need this, because you are not using the template argument.

You can simply do:

[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));
    }
}

你可以使用反射“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));
    }
}
answer2: 回答2:

Reflection.

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

This answer only relates to how to call a generic method. However in the actual case, it is much easier to just write the method again in a non-generic version. Because you only use TEntity in the context typeof(TEntity). Therefore you could simply search-and-replace typeof(TEntity) by entityType to get your non-generic version of the method.

反射。

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

这个答案只涉及如何调用泛型方法。然而,在实际的情况下,在非泛型版本中重新编写该方法就容易多了。因为在上下文类型只使用tentity(TEntity)。因此,你可以简单的搜索和替换型(TEntity)通过EntityType得到您的非泛型版本的方法。

answer3: 回答3:

Going from a Type to a generic call is a pain, but going from a generic call to a Type is easy. Can you swap your wrapper order?

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;
}

从一个类型到一个通用的调用是一个痛苦,但从一个通用的调用到一个类型是容易的。你能换一下包装单吗?

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;
}
c#  asp.net-mvc  asp.net-mvc-4  generics  razor