有条件地传递命名参数

发布于 2024-11-14 23:25:32 字数 1780 浏览 3 评论 0原文

我有一个结构体,它在构造函数中接受 3 个命名参数...

public struct MyData
{
    private readonly double _value1;
    private readonly double _value2;
    private readonly double _value3;

    public MyData(
        double value1 = 1.0,
        double value2 = 2.0,
        double value3 = 3.0)
    {
        _value1 = value1;
        _value2 = value2;
        _value3 = value3;
    }
}

创建该类的方法调用接收三个可空双精度数,仅当可空双精度数不为空时,我才想用它们来创建 MyData 类...

public MyData CreateMyData(double? value1, double? value2, double? value3)
{
    MyData myData;
    if (value1.HasValue)
    {
        if (value2.HasValue)
        {
            if (value3.HasValue)
            {
                myData = new MyData(value1, value2, value3); 
            }
            else
            {
                myData = new MyData(value1, value2); 
            }
        }
        else
        {
            if (value3.HasValue)
            {
                myData = new MyData(value1, value3: value3); 
            }
            else
            {
                myData = new MyData(value1); 
            }
        }
    }
    else
    {
        if (value2.HasValue)
        {
            if (value3.HasValue)
            {
                myData = new MyData(value2: value2, value3: value3); 
            }
            else
            {
                myData = new MyData(value2: value2); 
            }
        }
        else
        {
            if (value3.HasValue)
            {
                myData = new MyData(value3: value3); 
            }
            else
            {
                myData = new MyData(); 
            }
        }
    }
    return myData;
}

是有没有更好的方法来编写此方法而不修改 MyData 类?即我可以有条件地传递命名参数还是可以传递一个指示符来表示默认的命名参数值?

I have a struct which takes 3 named parameters in to the constructor...

public struct MyData
{
    private readonly double _value1;
    private readonly double _value2;
    private readonly double _value3;

    public MyData(
        double value1 = 1.0,
        double value2 = 2.0,
        double value3 = 3.0)
    {
        _value1 = value1;
        _value2 = value2;
        _value3 = value3;
    }
}

The method call that creates the class receives in three nullable doubles which I want to use to create the MyData class only if the nullable doubles are not null...

public MyData CreateMyData(double? value1, double? value2, double? value3)
{
    MyData myData;
    if (value1.HasValue)
    {
        if (value2.HasValue)
        {
            if (value3.HasValue)
            {
                myData = new MyData(value1, value2, value3); 
            }
            else
            {
                myData = new MyData(value1, value2); 
            }
        }
        else
        {
            if (value3.HasValue)
            {
                myData = new MyData(value1, value3: value3); 
            }
            else
            {
                myData = new MyData(value1); 
            }
        }
    }
    else
    {
        if (value2.HasValue)
        {
            if (value3.HasValue)
            {
                myData = new MyData(value2: value2, value3: value3); 
            }
            else
            {
                myData = new MyData(value2: value2); 
            }
        }
        else
        {
            if (value3.HasValue)
            {
                myData = new MyData(value3: value3); 
            }
            else
            {
                myData = new MyData(); 
            }
        }
    }
    return myData;
}

Is there a nicer way to write this method without modifying the MyData class? I.e. Can I conditionally pass named parameters or can I pass an indicator to represent the default named parameter value?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

蓝颜夕 2024-11-21 23:25:32
public MyData(
    double? value1 = null,
    double? value2 = null,
    double? value3 = null)
{
    _value1 = value1 ?? 1.0;
    _value2 = value2 ?? 2.0;
    _value3 = value3 ?? 3.0;
}

这样,您可以直接传递 null 而不会受到 组合的影响爆炸。

另外,如果您决定更改默认值,即使不重新编译此代码的所有用户,它也可以工作。

public MyData(
    double? value1 = null,
    double? value2 = null,
    double? value3 = null)
{
    _value1 = value1 ?? 1.0;
    _value2 = value2 ?? 2.0;
    _value3 = value3 ?? 3.0;
}

This way, you can pass the nulls directly and won't suffer from the combinatorial explosion.

Also, if you ever decide to change the defaults, it would work even without recompiling all users of this code.

一抹微笑 2024-11-21 23:25:32

检查这个

   public  MyData CreateMyData(double? value1, double? value2, double? value3)
    {
        var ss= typeof(MyData).GetConstructor(new Type[]{typeof(double),typeof(double),typeof(double)});
        var parametesr = ss.GetParameters();
        return new MyData(value1 ?? Convert.ToDouble(parametesr[0].DefaultValue), value2 ?? Convert.ToDouble(parametesr[1].DefaultValue), value3 ?? Convert.ToDouble(parametesr[2].DefaultValue)); 
    }

check this

   public  MyData CreateMyData(double? value1, double? value2, double? value3)
    {
        var ss= typeof(MyData).GetConstructor(new Type[]{typeof(double),typeof(double),typeof(double)});
        var parametesr = ss.GetParameters();
        return new MyData(value1 ?? Convert.ToDouble(parametesr[0].DefaultValue), value2 ?? Convert.ToDouble(parametesr[1].DefaultValue), value3 ?? Convert.ToDouble(parametesr[2].DefaultValue)); 
    }
转瞬即逝 2024-11-21 23:25:32

也许您只想:

return new MyData(value1 ?? 1.0, value2 ?? 2.0, value3 ?? 3.0);

Maybe you want just:

return new MyData(value1 ?? 1.0, value2 ?? 2.0, value3 ?? 3.0);

?

假扮的天使 2024-11-21 23:25:32
var t = typeof (MyData);
var c = t.GetConstructor(new Type[] { typeof(double), typeof(double), typeof(double)});
var p = c.GetParameters();
return new MyData(value1 ?? p[0].DefaultValue, value2 ?? p[1].DefaultValue, value3 ?? p[2].DefaultValue);
var t = typeof (MyData);
var c = t.GetConstructor(new Type[] { typeof(double), typeof(double), typeof(double)});
var p = c.GetParameters();
return new MyData(value1 ?? p[0].DefaultValue, value2 ?? p[1].DefaultValue, value3 ?? p[2].DefaultValue);
っ左 2024-11-21 23:25:32

您需要后期绑定才能执行此操作。开源框架 ImpromptuInterface 可让您访问动态选择命名参数

using ImpromptuInterface;

...

public MyData CreateMyData(double? value1, double? value2, double? value3)
{
    var arg = InvokeArg.Create;
    var argList = new List<Object>();
    if(value1.HasValue)
        argList.Add(arg("value1",value1));
    if(value2.HasValue)
        argList.Add(arg("value2",value2));
    if(value3.HasValue)
        argList.Add(arg("value3",value3));

    return Impromptu.InvokeConstructor(typeof(MyData), argList.ToArray());
}

You need late-binding to do this. The open source framework ImpromptuInterface gives you access to the DLR features needed to dynamically pick named arguments.

using ImpromptuInterface;

...

public MyData CreateMyData(double? value1, double? value2, double? value3)
{
    var arg = InvokeArg.Create;
    var argList = new List<Object>();
    if(value1.HasValue)
        argList.Add(arg("value1",value1));
    if(value2.HasValue)
        argList.Add(arg("value2",value2));
    if(value3.HasValue)
        argList.Add(arg("value3",value3));

    return Impromptu.InvokeConstructor(typeof(MyData), argList.ToArray());
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文