访问在Func<>;参数

本文关键字:参数 gt lt Func 访问 | 更新日期: 2023-09-27 18:20:27

看起来我错过了一些明显的东西,但真的不明白为什么我不能使用/访问分配给传入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;
    }
}

访问在Func<>;参数

这与委托无关,一切都与默认情况下所有参数都按值传递有关。如果factoryintstringStringBuilder,您会看到相同的行为。

如果希望Service构造函数修改参数的值,则需要refout参数。然而,我个人建议您将其更改为使用返回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参数而调用构造函数将是一个非常奇怪的代码。

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

您可以尝试将带有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();
    }
}

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

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

致问候,

您永远不会分配给Callee中的工厂,

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

我不确定你是否可以通过引用将参数传递给构造器。。。

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

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

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

编辑

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

public Service(out Func<string> factory)

public Service(ref Func<string> factory)