简体   繁体   English

访问已分配给传入的Func <>参数的方法

[英]Accessing a method which was assigned to a passed in Func<> parameter

Looks like I've missed something obvious but really can't figure out why I can't use/access a method which was assigned to a passed in Func<> parameter, I want to access/call it in the external calling context. 看起来我错过了一些显而易见的事情,但实际上无法弄清为什么我不能使用/访问分配给Func<>参数的方法,我想在外部调用上下文中访问/调用它。

Below the simple example: (real results data type is not string but some complex type) 在简单示例下面:(实际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;
    }
}

This has nothing to do with delegates, and everything to do with the fact that all arguments are passed by value by default. 这与委托无关,而与所有参数默认情况下都按值传递的事实无关。 You'd see the same behaviour if factory were an int , or a string , or a StringBuilder . 如果factoryintstringStringBuilder ,则会看到相同的行为。

If you want your Service constructor to modify the value of the argument, you need a ref or out parameter. 如果希望Service构造函数修改参数的值,则需要refout参数。 However, I would personally suggest that you change it to use a method which returns a Func<string> : 但是,我个人建议您将其更改为使用返回 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();
    }
}

(There are various other options here, such as a method group conversion, or a property. It's hard to know what to recommend when we don't have much context.) (这里还有许多其他选项,例如方法组转换或属性。当我们没有太多上下文时,很难知道该推荐什么。)

Obviously you'd want to rename the method. 显然,您想重命名该方法。 But calling a constructor solely to modify an out parameter would be a very odd bit of code. 但是仅调用构造函数来修改out参数将是非常奇怪的代码。

For more on parameter passing, see my article on the topic . 有关参数传递的更多信息,请参阅有关该主题的文章

Can you try pasing the func with an out parameter to the constructor of Service? 您可以尝试将带有out参数的func粘贴到Service的构造函数吗?

eg 例如

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();
    }
}

This will ensure the compiler knows to initialize the reference to factory parameter in the Service constructor. 这将确保编译器知道在Service构造函数中初始化对工厂参数的引用。 Otherwise you are just passing a reference to the null Func to the constructor by value then locally assigning the function to that variable on the stack inside the ctor. 否则,您只是通过值将对null Func的引用传递给构造函数,然后在ctor内部的堆栈上将该函数局部分配给该变量。

Please see this related question for clarity on ref and out parameters. 请参阅此相关问题,以更清楚地了解ref和out参数。

Best regards, 最好的祝福,

You never assign to the factory in the Callee, 您永远不会在被调用方分配工厂,

Since you are not passing the factory to the service by reference the updates to the variable will not be seen by the caller. 由于您没有通过引用将工厂传递给服务,因此调用者将看不到变量的更新。

I am uncertain whether or not you can pass parameters to a contructor by reference or not... 我不确定是否可以通过引用将参数传递给构造器...

To call a Func<T...> reference, you just need to call as though it were a normal method. 要调用Func<T...>引用,只需要像调用普通方法一样进行调用。 ie: 即:

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

Note that Func<string> will return a string type. 请注意, Func<string>将返回string类型。

EDIT 编辑

From your comment I have realised what you were actually asking in the OP. 从您的评论中,我已经意识到您在OP中的实际要求。 To be able to assign a value to any parameter, you need to mark it with out or ref . 为了能够为任何参数分配值,您需要使用outref对其进行标记。 So your declaration would look like: 因此,您的声明将如下所示:

public Service(out Func<string> factory)

or 要么

public Service(ref Func<string> factory)

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

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