1

我需要调用作为参数传递的委托方法,但由于此参数是可选的,我想将默认值设置为在“目标”类中实现的方法。

这是一个几乎可以按预期工作的示例:

public class AgeCalculator
{
    public void SetAge(Client client, Func<int, int> getAge = default(Func<int, int>))
    {
        client.Age = getAge != default(Func<int, int>) ? getAge(client.Id) : this.getAge(client.Id);
    }

    private int getAge(int clientId) {
        return 10;
    }
}

接着..

class Program
{
    static void Main(string[] args)
    {
        AgeCalculator calculator = new AgeCalculator();

        Client cli1 = new Client(1, "theOne");

        calculator.SetAge(cli1);//Sets 10
        calculator.SetAge(cli1, getAge);//Sets 5
    }

    private static int getAge(int clientId) {
        return 5;
    }
}

现在的问题;必须设置什么默认值才能避免询问委托值?

尝试了“public void SetAge(Client client, Func getAge = this.getAge)”,但没有成功。

AgeCalculator.getAge 上是否需要标签或不同的定义?我应该使用动态方法吗?

提前致谢。

注意:真实场景在面向TDD的项目中涉及更复杂的逻辑,这是一个总结情况的示例。

4

2 回答 2

7

方法参数的默认值必须是编译时常量。编写default(Func<...>)只是冗长的语法null,它是引用类型的默认值(作为委托,Func是引用类型),也是您可以在此上下文中使用的唯一默认值。

但是,您可以使用为该方法提供两个重载的老式方法做得更好:

public void SetAge(Client client)
{
    // Select any default value you want by calling the other overload with it
    SetAge(client, this.getAge);
}

public void SetAge(Client client, Func<int, int> getAge)
{
    client.Age = getAge(client.Id);
}
于 2013-08-14T20:31:16.190 回答
1

这基本上是按照您的要求做的,唯一的事情是,如果不使用 null,VS 给出的提示不会显示函数被用作默认值。如果这不是问题,那么这个解决方案在逻辑上与您将获得的一样接近。

public class AgeCalculator
{
    public void SetAge ( Client client , Func<int , int> getAge = null)
    {
        // assigns this.getAge to getAge if getAge is null
        getAge = getAge ?? this.getAge;
        client.Age = getAge( client.Id );
    }

    private int getAge ( int clientId )
    {
        return 10;
    }
}

如果您想动态更改默认设置器,您还可以将其设置为允许插入变量方法。这是相同的逻辑,只是另一种方式,如果您知道您将连续多次使用相同的功能,这将是有益的。

public class AgeCalculator
{
    public void SetAge ( Client client )
    {
        client.Age = GetAge( client.Id );
    }

    private Func<int,int> _getAge;
    public Func<int,int> GetAge 
    {
            private get
            {
                if(_getAge == null)
                    _getAge = getAge;
                return _getAge;
            }
            set
            {
                if(value == null)
                    _getAge = getAge;
                else
                    _getAge = value;
            }
    }

    private int getAge ( int clientId )
    {
        return 10;
    }
}

//assume we are in main
var cl = new Agecalculator();
var client = new Client(1,"theOne");
var client2 = new Client(2,"#2");

cl.SetAge(client); //set 10
cl.GetAge = getAge;
cl.SetAge(client); //set 5
cl.SetAge(client2); //set 5
于 2013-08-14T21:01:38.220 回答