【问题标题】:C# Constructor as Func (without reflection) [duplicate]作为 Func 的 C# 构造函数(没有反射)[重复]
【发布时间】:2014-05-23 18:22:25
【问题描述】:

我有一组配置对象,它们的构造函数都采用相同的参数。是否可以将构造函数分配给 Func 或类似的东西,以便可以以通用方式调用构造函数?

例如:

public class FooConfig : ConfigBase {
    public FooConfig(int a) { ... }
}

public class BarConfig : ConfigBase {
    public BarConfig(int a) { ... }
}

在调用代码中:

Func<int, ConfigBase> fooConfigCtr = FooConfig.FooConfig; // Obviously this doesn't work
FooConfig fooConfig = (FooConfig) fooConfigCtr(12345);

调用代码示例不是为了展示实际使用,只是为了说明为什么我在这种情况下使用 Func 有困难。

我发现的一种解决方法是在每个类上提供一个具有相同签名的静态工厂方法,并调用一个私有构造函数。但是,它有点不理想。

【问题讨论】:

  • 出于好奇,使用常规构造函数本身有什么问题?
  • 在调用代码中,我们希望以通用的方式调用构造函数,这需要将构造函数分配给Func或将工厂方法分配给Func。

标签: c# reflection function-pointers func


【解决方案1】:

您不必提供静态工厂方法。它可能不是您想要的,但您可以使用lambda expression,如下所示:

Func<int, ConfigBase> fooConfigCtr = n => new FooConfig(n);

【讨论】:

  • 谢谢,但我想避免额外的函数/lambda
  • @user3339997 您可以使用 lambda 表达式、反射或工厂方法。不幸的是,这些实际上是您使用 C# 的唯一选择,因为您不能将委托直接绑定到构造函数。
  • 好的,感谢您的澄清。这就是答案。
【解决方案2】:

如果您需要更动态的方式,可以这样做:

Func<int,ConfigBase> GetFactoryFunction(Type t)
{
    if(t == null) throw new ArgumentNullException("t");
    if(!typeof(ConfigBase).IsAssignableFrom(t)) throw new ArgumentException();

    return i => (ConfigBase)Activator.CreateInstance(t,i);
}

甚至是通用的:

Func<int,TDerived> GetFactoryFunction<TDerived>() where TDerived : ConfigBase
{
    return i => (TDerived)Activator.CreateInstance(typeof(TDerived),i);
}

【讨论】:

  • 激活器是反射,不是吗?
【解决方案3】:

试试这个:

    Func<int, ConfigBase> fooConfigCtr = a => new FooConfig(a);
    FooConfig fooConfig = (FooConfig)fooConfigCtr(12345);

如果没有 lambda 表达式,您可以尝试使用 Activator。

    Type typeOfYourClass = typeof (FooConfig);
    FooConfig fooConfig = (FooConfig)Activator.CreateInstance(typeOfYourClass, 12345);

【讨论】:

  • 谢谢,但我想避免额外的函数/lambda
猜你喜欢
  • 1970-01-01
  • 2020-07-04
  • 2016-07-07
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多