繁体   English   中英

如何传递以返回值为参数的动态方法?

[英]how can I pass a dynamic method with return value as parameter?

我有很多方法,需要将一些方法放入缓存中。 但我不希望它编辑每个方法。

如何传递以返回值为参数的动态方法? 请检查注释作为我代码中的一些问题。

谢谢您的提前。

private string GetUserName(string userId)
        {
            // how can I pass the method as parameter? 
            // Method is dynamic and can be any method with parameter(s) and return value
            return CacheIt<string>(item => GetUserNameFromDb(userId)); 
        }

        private T CacheIt<T>(Action<T> action) // Im not sure if this an Action
        {
            var key = "UserInfo." + userId; // how can I get the value of the parameter?

            var cache = MemoryCache.Default;
            var value = (T) cache[key];

            if (value != null)
                return value;

            value = action(); // how can I call the action or the method

            var policy = new CacheItemPolicy { SlidingExpiration = new TimeSpan(1, 0, 0) };
            cache.Add(key, value, policy);

            return value;

        }

        private string GetUserNameFromDb(string userId)
        {
            return "FirstName LastName";
        }

像这样修改CacheIt方法; 输入参数作为对象类型传递给方法,并且为了创建缓存键,将输入对象序列化为Json,并将json结果计算为MD5。 MD5结果作为key存储在高速缓存中。 另外, Action不返回值,我使用Func代替Action 我们期望返回用于缓存的值。

    private T2 CacheIt<T2>(Func<T2> func, object input)
    {
        var key = CreateMD5(JsonConvert.SerializeObject(input));
        var cache = MemoryCache.Default;
        var value = cache.Get(key);
        if (value != null)
        {
            return (T2)value;
        }
        value = func();
        var policy = new CacheItemPolicy { SlidingExpiration = new TimeSpan(1, 0, 0) };
        cache.Add(key, value, policy);
        return (T2)value;
    }

    private string CreateMD5(string input)
    {
        using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
        {
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hashBytes = md5.ComputeHash(inputBytes);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hashBytes.Length; i++)
            {
                sb.Append(hashBytes[i].ToString("X2"));
            }
            return sb.ToString();
        }
    }

最后, GetUserName和GetUserNameFromDb方法如下所示;

    private string GetUserName(string userId,string anotherParameter)
    {
        return CacheIt<string>(() => GetUserNameFromDb(userId, anotherParameter), new { userId,anotherParameter });
    }

    private string GetUserNameFromDb(string userId, string anotherParameter)
    {
        return "FirstName LastName";
    }

用法;

GetUserName("1","AnotherParameter");

注意:也许有更好的方法直接从CacheIt方法中的func获取输入参数。

我们可以通过方法动态传递方法,而不管方法定义如何

 public T CacheIt<T>(object container,string methodName,params object[] parameterlist)
    {
        MethodInfo func = container.GetType().GetMethod(methodName);
        var cache = MemoryCache.Default;
        T value = (T)cache.Get(func.Name);
        if(value!=null)
        {
            return value;
        }
        value = (T)func.Invoke(container,parameterlist);

        cache.Add(func.Name, value,new CacheItemPolicy());
        return value;

    }

    public void PrintUserName()
    {
     CacheIt<string>(this,nameof(this.GetUserName),"1");
        CacheIt<string>(this, nameof(this.GetFullName), "Raghu","Ram");
        Console.Read();
    }

    public string GetUserName(string userId)
    {
        // how can I pass the method as parameter? 
        // Method is dynamic and can be any method with parameter(s) and return value
        //return CacheIt<string>(item => GetUserNameFromDb(userId));
        return $"UserId : {userId} & UserName:Vaishali";
    }

    public string GetFullName(string FirstName,string  LastName)
    {
        return $"FullName : {string.Concat(FirstName," ",LastName)}";
    }

它可以与'out'和'ref'变量一起正常工作,但要获取out和ref变量的值并不容易,为此,我们必须对ParameterInfo进行更多工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM