如果您只是为调用者寻找稀疏语法,您可以使用匿名类型,类似于 jquery 传递可选选项的方式。示例:
public static void someFunction(object input)
{
foreach (var p in input.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
Console.WriteLine("{0}={1}", p.Name, p.GetValue(input));
}
函数本身有点杂乱,但对于调用者来说,语法相当轻量:
someFunction( new { Number = 3, Text = "Some text"});
输出:
Number=3
Text=Some text
如果您打算经常这样做,您可以使用扩展方法减轻痛苦。我在下面命名为Extract():
using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
public static class ExtensionMethods
{
public static Dictionary<string, object> Extract<T>(this T input) where T : class
{
return input
.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.ToDictionary( p => p.Name, p => p.GetValue(input));
}
}
public class Program
{
public static void someFunction(object input)
{
var parameters = input.Extract(); //Magic
Console.WriteLine("There were {0} parameters, as follows:", parameters.Count);
foreach (var p in parameters)
{
Console.WriteLine("{0}={1}", p.Key, p.Value);
}
}
public static void Main()
{
someFunction(new { number = 3, text = "SomeText" } );
someFunction(new { another = 3.14F, example = new DateTime(2017, 12, 15) } );
}
}
DotNetFiddle 上的输出:
There were 2 parameters, as follows:
number=3
text=SomeText
There were 2 parameters, as follows:
another=3.14
example=12/15/2017 12:00:00 AM
这种方法的主要缺点是您不能使用接口或执行任何要求某些键存在的操作。此外,您必须使用反射,这需要更多的工作。如果您想避免这些缺点,您可以使用相同的方法,但使用非匿名类型,如下所示:
class SomeFunctionParams
{
public int Number { get; set; }
public string Text { get; set; }
}
public static void someFunction(SomeFunctionParams params)
{
Console.WriteLine("Number={0}", params.Number);
Console.WriteLine("Text={0}", params.Text);
}
...但是你会失去匿名类型的动态优势。
另一种选择是将所有可能的键作为可选参数公开,并且只提供你想要的:
void someFunction(int Number = default(int), string Text = default(string), DateTime SomeOtherParam = default(DateTime))
{
if (Number != default(int)) Console.WriteLine("Number={0}", Number);
if (Text != default(string)) Console.WriteLine("Text={0}", Text);
if (SomeOtherParam != default(DateTime)) Console.WriteLine("SomeOtherParam={0}", SomeOtherParam);
}
someFunction(Number : 3, Text : "Some text");