在调用方法时使用字典参数作为可选参数

时间:2018-02-22 21:41:13

标签: c# optional-parameters

我正在尝试使用字典值来在调用方法时命名可选参数。我不确定c#是否可行,但我使用动态SQL做了类似的事情。

,

我的同事建议我通过删除所有可选参数来改变方法本身,而是通过包含所有参数的字典并在方法内处理它们。

我认为这样可行,但出于好奇心的缘故,我想得到一些反馈,并找出我在上述代码中尝试做的事情是否可行。

如果不可能,但有另一种方法可以达到预期的结果,我很乐意看到你的建议。

提前谢谢。

1 个答案:

答案 0 :(得分:1)

传递表达式

由于条件是在事后使用的(即通过过滤完整的结果集),因此可以使用LINQ过滤结果。为了获得最大的灵活性,调用者可以传入Expression作为每个项目的回调,以确定是否应该包含它。

获取过滤结果集:

public IEnumerable<Patient> FindPatients(Func<Patient,bool> criteria)
{
    return sourceData
        .Where (criteria);
}

要返回单个结果:

public Patient FindPatient(Func<Patient,bool> criteria)
{
    return sourceData
        .Single(criteria);
}

criteria表达式只是一个接受患者并返回布尔值的函数。调用者可以以任何方式编写它,或者将其作为lambda表达式插入。

var results = patients.FindPatients( p => p.LastName == "Doe" );

或者

var results = patients.FindPatients
(   
    p =>
    p.LastName.Contains("Doe") && 
    p.PracticeID == 12 
);

或者

    var singleResult = patients.FindPatient( p => p.UserID == 1);

正如您所看到的,呼叫者可以提供任何所需的标准,并具有类型安全和早期绑定的好处。这远远优于使用既没有。

的词典

完整的示例代码:

class Patient
{
    public int      UserID     { get; set; }
    public int      PracticeID { get; set; }
    public string   FirstName  { get; set; }
    public string   LastName   { get; set; }
    public DateTime DOB        { get; set; }
    public string   Social     { get; set; }
    public override string ToString()
    {
        return string.Format("{0} {1} {2}", UserID, FirstName, LastName);
    }
}

class PatientRepository
{
    static private readonly List<Patient> sourceData = new List<Patient>
    {
        new Patient
        {
            UserID = 1, PracticeID = 10, FirstName = "John", LastName = "Doe", DOB = DateTime.Parse("1/2/1968"), Social="123456789"
        },
        new Patient
        {
            UserID = 2, PracticeID = 10, FirstName = "Jane", LastName = "Doe", DOB = DateTime.Parse("1/2/1958"), Social="123456790"
        },
        new Patient
        {
            UserID = 3, PracticeID = 10, FirstName = "John", LastName = "Carson", DOB = DateTime.Parse("4/1/1938"), Social="123456791"
        }
    };

    public IEnumerable<Patient> FindPatients(Func<Patient,bool> criteria)
    {
        return sourceData
            .Where (criteria);
    }
    public Patient FindPatient(Func<Patient,bool> criteria)
    {
        return sourceData
            .Single(criteria);
    }
}

public class Program
{
    public static void Main()
    {
        //Get a reference to the data store
        var patients = new PatientRepository();

        Console.WriteLine("Multiple record search");
        var results = patients.FindPatients
        ( 
            p => p.LastName == "Doe" 
        );
        foreach (var p in results)
        {
            Console.WriteLine(p);
        }

        Console.WriteLine("Single record search");
        var singleResult = patients.FindPatient
        (
            p => p.UserID == 1
        );
        Console.WriteLine(singleResult);
    }
}

输出:

Multiple record search
1 John Doe
2 Jane Doe
Single record search
1 John Doe

See the working code on DotNetFiddle