【问题标题】:Send method return type as generic发送方法返回类型为泛型
【发布时间】:2021-10-15 09:45:57
【问题描述】:

我在使用 redis 通用缓存时遇到了一些问题,因为 redis 将值存储为 json,我必须将其反序列化到我的模型中,但我不能,因为我使用的是通用方法,我无法解决这个问题。

Redis 获取操作:

 public T Get<T>(string key)
    {
        var type = typeof(T);
        var result = default(object);
        RedisInvoker(x => { result = x.Get<object>(key); });
        var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
        var deserializedObj = JsonConvert.DeserializeObject<T>(result.ToString(), settings);
        return deserializedObj;
    }
  public object Get(string key)
    {
        var result = default(object);
        RedisInvoker(x => { result = x.Get<object>(key); });
        return result;
    }

缓存拦截:

  public override void Intercept(IInvocation invocation)
    {
        var methodName = string.Format($"{invocation.Method.ReflectedType.FullName}.{invocation.Method.Name}");
        var arguments = invocation.Arguments.ToList();
        var key = $"{methodName}({string.Join(",", arguments.Select(x => x?.ToString() ?? "<Null>"))})";
        if (_cacheManager.IsAdded(key))
        {
            invocation.ReturnValue = _cacheManager.Get(key);
            return;
        }
        invocation.Proceed();
        _cacheManager.Add(key, invocation.ReturnValue, _duration);
    }

我想要做的是获取方法的 returnType 也是泛型的,并将其发送到具有泛型类型的 Get 方法。但我不能这样发送:

 var returnType = invocation.Method.ReturnType;
        if (_cacheManager.IsAdded(key))
        {
            invocation.ReturnValue = _cacheManager.Get<returnType>(key);
            return;
        }

错误是:

returnType 是一个变量,但用作类型

【问题讨论】:

  • if (invocation.Method.IsGenericMethod()) methodName+="&lt;"+string.Join(",",invocation.Method.GetGenericArguments().Select(a =&gt; a.Name))+"&gt;"; 什么的...
  • 要拨打Get&lt;T&gt;,您需要拨打methodinfo.MakeGenericMethod(type).Invoke(...)。改为添加.Get(Type t, ...) 方法会更容易。
  • 你能完整回答吗,我听不懂:/

标签: c# generics .net-core redis


【解决方案1】:

所以你想用你只在运行时知道的类型调用.Get&lt;T&gt;。简单的答案是; “别”。而是创建一个可以轻松调用的非泛型方法;

public object Get(Type type, string key) {...}
public T Get<T>(string key) => (T)Get(typeof(T), key);

因为替代方案涉及反射;

invocation.ReturnValue = typeof(...)
    .GetMethod("Get")
    .MakeGenericMethod(returnType)
    .Invoke(instance, new object[]{ key });

【讨论】:

  • "简单的答案是;"不要"" - 我会说答案是使用反射。我不会说“不要”。
  • 因为这是一个 XY 问题。 “我想做 X”,“简单的答案实际上是 Y”。
  • 你这是什么意思?这在这里如何应用?
  • 一个典型的XY问题释义; “我把自己画到了这个角落,现在我想我需要解决这个问题”。好的答案; “虽然这个问题很难,但这是你解决它的方法”。更好的答案; “不要把自己画到那个角落,而是解决这个问题”。请注意,我都做了...
  • 我知道什么是 XY 问题。我只是不明白它在这里如何应用?
猜你喜欢
  • 2016-12-24
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多