【问题标题】:c# dynamic and extension method solution?c#动态和扩展方法解决方案?
【发布时间】:2013-01-18 05:29:57
【问题描述】:

我在Base class 中有一个方法调用(通过反射到 另一个 方法)。

  type.InvokeMember(context.Request["MethodName"],
                    System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, 
                    null, 
                    this, 
                    new object[] { context, Jobj });   //  jObj is dynamic

jObj 参数类型为dynamic(无法更改此类型)。

如果MethodName 字符串值为:“getFinanceDetails”,则调用该方法..

void getFinanceDetails(object contextObj, dynamic obj)
{

  //Here I need to do obj["Inv_num"].ToString().Decrpyt()   ( my extension method).
  //but it goes Bang cause I cant use extension method for dynamic.
  //But I cant also send it decrypted from base cause not all values are encrpyrted.

}

但是 - 我确实通过使用(在方法内部)解决了它:

((object) obj["Inv_num"]).ToString().Decrypt();

但我不想每次都转换为 object ,只是为了启用扩展方法。

我可以用 param 类型发送 做些什么来修复它?

我的愿望:

我希望能够做到:obj.ToString().Decrpyt() obj["Inv_num"].ToString().Decrpyt()

编辑

   public static string Decrypt(this string obj)
        {
            Func<string, string> Decrypt = Encryptions.GetDecryptedCode;
            return Decrypt(obj);

        }
  • obj(在这种情况下IDictionary&lt;string , object&gt;)。 所以我应该能够读取属性。 (此示例中的 inv_num。

【问题讨论】:

  • 你没有给我们足够的信息。您的扩展方法究竟是什么? obj.ToString() 返回什么? ["Inv_nim"]的相关性是什么?
  • 你不能在调用方法之前强制转换 jObj 吗? new object[] { (YourType)jObj }) ?
  • @JonSkeet 已编辑。谢谢。
  • @RoyiNamir:你为什么期望ToString()知道返回obj["Inv_num"]
  • @JonSkeet ToString 仅适用于this string obj 的扩展方法。(如果我理解你的问题)

标签: c# .net dynamic reflection


【解决方案1】:

可能不完全是您正在寻找的语法,但您可以将扩展方法称为动态对象上的简单静态方法:

void getFinanceDetails(object contextObj, dynamic obj)
{
    var decryptedValue = MyExtensions.Decrypt(obj);
}

这显然假设在运行时obj 是您的扩展方法所操作的正确类型。在您的问题中,您已经显示了一些 obj["Inv_num"] 好像 obj 是一个复杂类型,具有一个名为 Inv_num 的属性,它是字符串类型。所以你可能需要调整正确类型的调用:

var decryptedValue = MyExtensions.Decrypt(obj["Inv_num"]);

【讨论】:

  • 谢谢,但我试图阻止这个方法调用包装器。并且只做“流利”的方法调用像x.Do().Do2()
  • 您不能在动态对象上调用扩展方法。您使用的编程语言 (C#) 不支持此功能。我已经向您提出了一种解决方法。另一种解决方法是根本不使用任何dynamic 类型。
【解决方案2】:

假设obj["Inv_num"].ToString() 已经返回正确的值,您可以分两步轻松完成:

string text = obj["Inv_num"].ToString();
var decrypted = text.Decrypt();

说实话,不清楚为什么getFinanceDetails(应该更改为遵循.NET 命名约定)不能写成:

void getFinanceDetails(object contextObj, IDictionary<string, object> obj)
{
    var decrypted = obj["Inv_num"].ToString().Decrypt();
}

您是否需要用实现IDictionary&lt;string, object&gt;的东西来调用它?

【讨论】:

  • getFinanceDetails 不能被称为对象,因为我不能这样做:obj [“xxx”]。 (在运行时类型是字典......]
  • @RoyiNamir:但你最初的问题是说你只是想能够做到obj.ToString().Decrypt() - 没有提到obj["Inv_num"]。您对自己的要求非常不清楚。 (你能把类型改成IDictionary&lt;string, object&gt;吗?
  • 我认为为什么getFinanceDetails 不能按建议重写的原因很清楚:这是因为动态表达式是在运行时评估的,但扩展方法是由编译器重建的(在编译时)。所以运行时会尝试调用obj.Decrypt() 而不是Extensions.Decrypt(obj),因为编译器不知道应该调用扩展方法。
  • 是的,它确实有效。我改为签名作为您的解决方案。现在我可以做到obj["Inv_num"].ToString().Decrypt()
  • Jon 您的意思是 遵循 .net 约定:更改为 [g] 吗?大写?或将其名称更改为FinanceGetDetails 或两者兼而有之?或无
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
相关资源
最近更新 更多