不,主要是因为这种模式相当僵化。例如,如果您想要一个不会设置为字段的参数怎么办?那是什么语法?您可能想出的大多数解决方案要么是限制性的,要么与当前方法一样冗长。
不过,这种刚性只是一般情况下的问题。如果这个模式适合你,那么你可以通过继承来定义它,这是适合这项工作的工具。
因此,您可以定义一组可以继承自的通用 Tuple<> 类类:
public abstract class TupleBase<T1>
{
public T1 Argument1 { get; private set; }
public TupleBase(T1 argument1)
{
this.Argument1 = argument1;
}
}
public abstract class TupleBase<T1, T2>
{
public T1 Argument1 { get; private set; }
public T2 Argument2 { get; private set; }
public TupleBase(T1 argument1, T2 argument2)
{
this.Argument1 = argument1;
this.Argument2 = argument2;
}
}
public abstract class TupleBase<T1, T2, T3>
{
public T1 Argument1 { get; private set; }
public T2 Argument2 { get; private set; }
public T3 Argument3 { get; private set; }
public TupleBase(T1 argument1, T2 argument2, T3 argument3)
{
this.Argument1 = argument1;
this.Argument2 = argument2;
this.Argument3 = argument3;
}
}
// Etc..
然后
class MyClass
{
int var1;
int var2;
int var3;
int var4;
public MyClass(int var1, int var2, int var3, int var4){
this.var1 = var1;
this.var2 = var2;
this.var3 = var3;
this.var4 = var4;
}
}
变成
class MyClass : TupleBase<int, int, int, int>
{
public MyClass(int var1, int var2, int var3, int var4)
: base(var1, var2, var3, var4)
{
}
}
.
继承是基本正确的工具,因为您希望MyClass 采用基本模式,即继承它。您在 C# 中遇到的问题是您一次只能从一个类继承,因此您不能在所有情况下都添加这样的附加功能。
或者,你可以写
class MyClass
{
int var1;
int var2;
int var3;
int var4;
public MyClass(int var1, int var2, int var3, int var4){
this.SetConstructorValues(var1, var2, var3, var4);
}
}
,其中.SetConstructorValues() 是通用扩展方法
private static System.Collections.ConcurrentDictionary<Type, Action<object, object[]>> ConstructorSetterDictionary { get; private set; }
public static void SetConstructorValues<T_SetClass>(
this T_SetClass instanceToSetValuesFor
, params object[] constructorArguments
)
{
var instanceType = typeof(T_SetClass);
Action<object, object[]> constructorSetterAction;
if (!ConstructorSetterDictionary.TryGetValue(
instanceType
, out constructorSetterAction
))
{
throw new Exception("Populate the dictionary! Also change this Exception message; it's from a StackOverflow example and not really designed to actually be written like this.");
}
constructorSetterAction(
instanceToSetValuesFor
, constructorArguments
);
}
,其中ConstructorSetterDictionary 是每个Type 的setter-Action<object, object[]> 的字典,根据您喜欢的任何逻辑推断(例如,将带有参数名称的构造函数与字段匹配),在程序启动时使用反射。
从概念上讲,基于对象的Type 获取这样的方法基本上是虚拟方法的工作方式,其中ConstructorSetterDictionary 是虚拟查找表。
我发现这种元编程在我自己的工作中很有用,但请注意,在某些时候,它不再是 C#。