我试图以一种相当通用的方式构造一些对象。一些对象有构造函数参数,其他对象没有。
我想要实现的是返回某种构建器函数,如果需要,我可以提供构造函数参数。
我知道我可以传递可选参数,但在我的实际情况中,有几个层,我讨厌在层次结构中添加可选参数。
我对部分申请/讨论不太满意,但我可以在这里使用,如果是,怎么样?
这里有一些示例代码 - 它们不会起作用 - 试图解释我之后的更多内容。
public void Main()
{
dynamic buildClass = ClassBuilder<BaseClass>(true);
// ideally I'd like to be able to supply the constructor data
// here
var theClass = buildClass(???)
}
public Func<???, TClass> ClassBuilder<TClass>(bool flag) where TClass : BaseClass
{
// obviously this won't work since the delegates have different
// signatures
if (flag) return () => GetClassA();
return (x) => GetClassB(x);
}
public object GetClassA()
{
return new ClassA();
}
public object GetClassB(string param)
{
return new ClassB(param);
}
public class BaseClass {}
public class ClassA : BaseClass {}
public class ClassB : BaseClass
{
private string _param;
public ClassB(string param)
{
_param = param;
}
}
很多thx
取值
答案 0 :(得分:2)
要详细说明@Sylwekqaz,您可以使用下面的内容,而不是限制自己BaseClass
的类型。
public static class Builder
{
public static T Build<T>(params object[] args) where T : class
{
var info = typeof(T).GetConstructor(args.Select(arg => arg.GetType()).ToArray());
if (info == null)
throw new ArgumentException(@"Can't get constructor :(", "args");
return (T)info.Invoke(args.ToArray());
}
}
然后你可以将你的建设者称为
var a = Builder.Build<ClassA>();
var b = Builder.Build<ClassB>(); // need parameterless ctor in ClassB
var c = Builder.Build<ClassB>("param");
答案 1 :(得分:1)
您必须使用代码反射来检测带有参数的构造函数/方法并调用它。
Type type = typeof(YourClass);
ConstructorInfo ctor = type.GetConstructor(new[] { typeof(string) });
object instance = ctor.Invoke(new object[] { 10 });
〜来源:Using C# reflection to call a constructor
如果必须使用方法GetClassX
,则可以使用MethodInfo类更多信息
https://msdn.microsoft.com/en-us/library/system.type.getconstructor%28v=vs.110%29.aspx
https://msdn.microsoft.com/en-us/library/system.reflection.constructorinfo.invoke%28v=vs.110%29.aspx
答案 2 :(得分:1)
我并不完全遵循您的代码示例,但您会询问部分应用和currying ......
我发现的最好的方法是创建N个函数,这些函数取自1-N通用参数,然后让编译器选择你想要的那个。如果您查看我的language-ext项目,我有两个函数,一个名为curry
,一个名为par
,用于currying和部分应用:
要部分申请,请执行以下操作:
// Example function
int AddFour(int a,int b,int c, int d)
{
return a + b + c + d;
}
// This returns a Func<int,int,int> with the first two arguments 10 & 5 auto-provided
var tenfive = par(AddFour, 10, 5);
// res = 10 + 5 + 1 + 2
var res = tenfive(1,2);
要咖喱,请这样做:
// Example function
int AddFour(int a,int b,int c, int d)
{
return a + b + c + d;
}
// Returns Func<int,Func<int,Func<int,Func<int,int>>>>
var f = curry(AddFour);
// res = 10 + 5 + 1 + 2
var res = f(10)(5)(1)(2);