1

看起来我错过了一些明显的东西,但真的不知道为什么我不能使用/访问分配给传入Func<>参数的方法,我想在外部调用上下文中访问/调用它。

下面是简单的例子:(真正的results数据类型不是string一些复杂的类型)

class Caller
{
    private Func<string> factory;

    public Caller()
    {
        this.factory = null;
        var adapter = new Adapter(this.factory);
        adapter.Adapt(...);

        // then I would share this factory via IoC
        dependencyContainer.RegisterUsingFactoryMethod<string>(this.factory);

        // !!! but here is factory still not assigned
        string results = this.factory();
    }
}

class Adapter
{
    private string results;

    public Adapter(Func<string> factory)
    {
        factory = () => this.results;
    }

    public IOut Adapt(IIn input)
    {
       this.results = someCalculatedData;
    }
}
4

4 回答 4

4

这与委托无关,与所有参数默认按值传递的事实有关。factory如果是a 或 aint或 a string,您会看到相同的行为StringBuilder

如果你想让你的Service构造函数修改参数的值,你需要一个reforout参数。但是,我个人建议您将其更改为使用返回a的方法Func<string>

public class Caller
{
    private readonly Func<string> factory;

    public Caller()
    {
        this.factory = Service.GetFunc();
    }
}

public class Service
{
    public static Func<string> GetFunc()
    {
        return () => Guid.NewGuid().ToString();
    }
}

(这里还有各种其他选项,例如方法组转换或属性。当我们没有太多上下文时,很难知道该推荐什么。)

显然你想重命名该方法。但是仅仅为了修改参数而调用构造out函数将是一段非常奇怪的代码。

有关参数传递的更多信息,请参阅我关于该主题的文章

于 2012-01-17T11:59:27.640 回答
3

您可以尝试将带有 out 参数的 func 传递给 Service 的构造函数吗?

例如

class Caller
{
    private Func<string> factory;

    public Caller()
    {
        this.factory = null;
        var service = new Service(out this.factory);

        // !!! but here is factory still not assigned
        string results = this.factory();
    }
}

class Service
{
    public Service(out Func<string> factory)
    {
        factory = () => Guid.NewGuid().ToString();
    }
}

这将确保编译器知道在 Service 构造函数中初始化对工厂参数的引用。否则,您只是通过值将对 null Func 的引用传递给构造函数,然后将函数本地分配给 ctor 内部堆栈上的该变量。

请参阅此相关问题以了解 ref 和 out 参数。

最好的祝福,

于 2012-01-17T11:57:25.377 回答
2

你永远不会在 Callee 中分配给工厂,

由于您没有通过引用将工厂传递给服务,因此调用者不会看到对变量的更新。

我不确定您是否可以通过引用将参数传递给构造函数...

于 2012-01-17T11:54:01.313 回答
0

要调用Func<T...>引用,您只需像调用普通方法一样调用即可。IE:

class Service
{
    public Service(Func<string> factory)
    {
        string result = factory();
    }
}

请注意,这Func<string>将返回一个string类型。

编辑

从您的评论中,我已经意识到您在 OP中实际问的是什么。为了能够为任何参数赋值,您需要用out或标记它ref。所以你的声明看起来像:

public Service(out Func<string> factory)

或者

public Service(ref Func<string> factory)
于 2012-01-17T11:54:39.637 回答