【问题标题】:c# - How to change Func<T> argumentsc# - 如何更改 Func<T> 参数
【发布时间】:2015-12-17 21:36:05
【问题描述】:

我有以下功能:

protected static T WrapException<T>(Func<T> function)
{
    T result = default(T);

    WrapException(delegate
    {
        result = function();
    });
    return result;
}

我在我的所有 WCF 项目服务端点中都使用此功能:

public List<ResultDTO> GetSomething(SessionDto sessionDto)
{
    return WrapException(() => _someFacade.Get(sessionDto));
}

我需要在调用操作之前更改 WrapException 处 sessionDto 的值。

我尝试通过以下演员来访问它:

((dynamic)function.Target)

它工作正常,但是当我尝试访问参数时,它会引发异常。

我做错了什么?

Obs:对不起,我的英语不是我的母语

【问题讨论】:

  • 如果您在截屏之前将 Windows 语言更改为英语,您的错误消息应该是英语。这将极大地帮助网站上的其他人为您提供帮助。
  • 你想在什么时候访问/更改sessionDto
  • 但是您已经证明您看不到该值,更不用说更改它了 - 您只是在监视窗口中看到元数据。正如它在链接问题中所说 - “如果你想获取参数,你将不得不传递表达式。通过传递“Func”,你将传递编译的 lambda,所以你不能再访问表达式树了”。
  • 请注意How to: Modify Expression Trees - “表达式树是不可变的,这意味着它们不能直接修改。要更改表达式树,您必须创建现有表达式树的副本,并且在创建时副本,进行必要的更改。”
  • Func&lt;T, object&gt; 有一个类型为 T 的参数并返回一个类型为 object 的实体 - Func&lt;T&gt; 没有参数并返回一个类型为 T 的实体。

标签: c# wcf


【解决方案1】:

您的问题的答案是,不可能以安全的方式做到这一点。

您可以尝试在Target 对象中编辑sessionDto。这是一个自动生成的 lambda 闭包字段。此结构未记录在案。它随时可能改变。

即使你让它工作,这也是糟糕的架构,因为你正在触及另一段代码的内部。

您可能应该重构代码,这样就不必编辑另一个函数的局部变量(!)。

【讨论】:

  • 问题是我无法更改 Target 中的 sessionDto,当我尝试这样做时,它在我的问题的最后一个屏幕截图中抛出了异常。 “对象”不包含“sessionDto”
  • 您不能使用动态访问私有成员。使用反射。
  • 我做到了,看看问题截图
  • 你这是什么意思?我知道您“这样做了”,但这是错误的,您不应该那样做。使用反射。
猜你喜欢
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多