C# 方法,该方法仅具有仅对设置参数有效的可选参数

C# 方法,该方法仅具有仅对设置参数有效的可选参数,c#,C#,我想写一个有可选参数的方法。它应该只使用指定给它的参数更新某些对象,而保留其他属性不变 有问题的部分是: Null是所有对象属性的有效值 无法读取对象属性的值以与进行比较 方法的签名应该是什么,方法的逻辑应该是什么 假设对象看起来像这样: public class Foo { public int Id { get; set; } public bool? MyBool { get; set; } public int? MyInt { get; set; }

我想写一个有可选参数的方法。它应该只使用指定给它的参数更新某些对象,而保留其他属性不变

有问题的部分是:

  • Null是所有对象属性的有效值
  • 无法读取对象属性的值以与进行比较
方法的签名应该是什么,方法的逻辑应该是什么

假设对象看起来像这样:

public class Foo
{
    public int Id { get; set; }
    public bool? MyBool { get; set; }
    public int? MyInt { get; set; }
    public string MyString { get; set; }
}
public void UpdateObject(int id, bool? optBool = null, int? optInt = null,
                          string optString = null)
{
    var objectToUpdate = _fooList.FirstOrDefault(x => x.Id = id);

    if(objectToUpdate != null)
    {
        // Update only set properties?
    }
}
// at some part of app
UpdateObject(1, optInt: 5);
// will set the int property to 5 and leaves other properties unchanged

// at other part of app
UpdateObject(1, optString: "lorem ipsum");
// will set the string property and leaves other properties unchanged

// at other part of app
UpdateObject(1, optBool: null, optString: "lorem ipsum");
// will set the string and bool property and leaves other properties unchanged
假设该方法如下所示:

public class Foo
{
    public int Id { get; set; }
    public bool? MyBool { get; set; }
    public int? MyInt { get; set; }
    public string MyString { get; set; }
}
public void UpdateObject(int id, bool? optBool = null, int? optInt = null,
                          string optString = null)
{
    var objectToUpdate = _fooList.FirstOrDefault(x => x.Id = id);

    if(objectToUpdate != null)
    {
        // Update only set properties?
    }
}
// at some part of app
UpdateObject(1, optInt: 5);
// will set the int property to 5 and leaves other properties unchanged

// at other part of app
UpdateObject(1, optString: "lorem ipsum");
// will set the string property and leaves other properties unchanged

// at other part of app
UpdateObject(1, optBool: null, optString: "lorem ipsum");
// will set the string and bool property and leaves other properties unchanged
现在,我想调用该方法来更新应用程序不同部分的属性,如下所示:

public class Foo
{
    public int Id { get; set; }
    public bool? MyBool { get; set; }
    public int? MyInt { get; set; }
    public string MyString { get; set; }
}
public void UpdateObject(int id, bool? optBool = null, int? optInt = null,
                          string optString = null)
{
    var objectToUpdate = _fooList.FirstOrDefault(x => x.Id = id);

    if(objectToUpdate != null)
    {
        // Update only set properties?
    }
}
// at some part of app
UpdateObject(1, optInt: 5);
// will set the int property to 5 and leaves other properties unchanged

// at other part of app
UpdateObject(1, optString: "lorem ipsum");
// will set the string property and leaves other properties unchanged

// at other part of app
UpdateObject(1, optBool: null, optString: "lorem ipsum");
// will set the string and bool property and leaves other properties unchanged

请注意,仅设置值将不起作用,因为它将用null覆盖不需要的属性

public void UpdateObject(int id, bool? optBool = null, int? optInt = null,
                          string optString = null)
{
    var objectToUpdate = _fooList.FirstOrDefault(x => x.Id = id);

    if(objectToUpdate != null)
    {
        // This is wrong
        objectToUpdate.MyBool = optBool;
        objectToUpdate.MyInt = optInt;
        objectToUpdate.MyString = optString;
    }
}

而不是传递新值。传入提供新值的
Func
。如果Func为null,则不执行任何操作。仅当Func返回null时,才将该值设置为null

public void UpdateObject(Func<int> idProvider, Func<bool?> optBoolProvider = null, Func<int?> optIntProvider = null,
                          Func<string> optStringProvider = null)
{
    if(idProvider != null) Id = idProvider(); // etc.
}
如果您可以读取当前值,另一种选择是
Func
,而不是默认为null,而是默认为identity,即x->x。然后,您不需要执行空检查(除非作为合同,如果必须的话)

public void UpdateObject(Func-idProvider,Func-optBoolProvider=x=>x,Func-optiontprovider=x=>x,
Func optStringProvider=x=>x)
{
Id=idProvider(Id);//等等。
}

我最近在java领域,因此如果语法关闭,我深表歉意。

您可以重载函数,让您可以选择添加哪些变量以及保持哪些变量不变

这样,您可以选择仅更改要更改的给定对象的值

您还可以执行以下操作:

public Foo changeString(Foo f, string s) 
{
    f.myString = s;
    return f;
}
public Foo changeInt(Foo f, int i)
{
    f.myInt = i;
    return f;
}

//external piece of code
Foo f = new Foo ();
f = changeInt(f, 5).changeString(f, "abc");

这将链接函数并编辑两个属性,而不涉及任何其他内容。也许这可以帮助您解决问题。

如果
null
是一个有效值,您需要用bool来包装每个值,指示应该写入它,比如
newupdateableprop{Name=“optBool”,value=null}
。或者为每个参数添加一个bool参数,表示相同。您可以使用类型为的enum的单个属性来编码必须序列化的属性。生成器模式,好主意!但是我真的在寻找一种方法来保持更新逻辑。