如何在构造函数中根据某个参数调用基础构造函数?

9
如何在构造函数中根据参数调用基本构造函数?例如:
public SomeConstructor (){
       if(SomeParameter == "something") //here call base("something");
          else //here call base("something else")
}

在我的例子中
SomeParameter

这个名字可能是本地计算机名称。

为了解释我在做什么,我想根据计算机名称确定构造函数。我正在开发MVC项目,当我发布项目到服务器时,我经常忘记更改连接字符串的名称。因此,我希望指定如果计算机名称 == 我的计算机名称,则调用

:base("DefaultConnection")

否则,例如,调用:

:base("ServerConnectionString")

1
我已经编辑了你的标题。请查看“Should questions include “tags” in their titles?”,在那里达成的共识是“不应该包含标签”。 - John Saunders
好的,抱歉。下次我不会这样做。 - Adrian Księżarczyk
4个回答

11
您不能这样做,只能像后面的例子一样调用,并且即使是这样,两个例子都传递了一个字符串而没有更改参数类型,所以这种方式似乎是无意义的(您甚至没有调用不同的构造函数)。在常规方式下,您可以通过确保提供的值是有效值来避免这种情况。作为一个随口的例子,考虑以下内容:
public SomeConstructor() 
  : base(Configuration.ConnectionString) {

}

public static Configuration {
  public static string ConnectionString {
    get { 
      /* some logic to determine the appropriate value */
#if DEBUG
      return ConfigurationManager.ConnectionStrings["DebugConnectionString"]; 
#else
      return ConfigurationManager.ConnectionStrings["ReleaseConnectionString"]; 
#endif
    } 
  }
}

非常感谢你的帮助。它非常好用。我不知道为什么之前没有想到这个主意:) 谢谢 - Adrian Księżarczyk

3

你不能调用不同的构造函数,但是你可以通过使用条件运算符将不同的值传递到相同的构造函数中:

public SomeConstructor ()
  : base(SomeParameter == "something" ? "something" : "something else") {
}

如果您需要使用不同的基本构造函数,则需要为每个构造函数创建一个,然后使用静态方法在不同的构造函数之间进行选择。例如:

private SomeConstructor() : base("some", "thing") {}

private SomeConstructor(bool flag) : base("some", "other", "thing") {}

public SomeConstructor Create() {
  if (SomeParameter == "something") {
    return new SomeConstructor();
  } else {
    return new SomeConstructor(true);
  }
}

(我在这里使用了布尔类型的参数,只是为了使构造函数的签名不同。您可能有不同的数据要传递给它们,因此您不需要以这种方式区分它们。)

2

试试这个:

public class TestInherit : Child
{
    public TestInherit()
        : base(Environment.MachineName=="MyPC" ? "here" : "there")
    {
    }

}

public class Child
{
    public Child(string name) { }
}

谢谢你。你的想法也非常有用。谢谢。 - Adrian Księżarczyk

1

使用一个连接字符串,根据构建配置使用不同的值。这可以通过配置文件转换来实现。

Web.config中使用

  <connectionStrings>
    <add name="Foo" connectionString="DefaultConnection" />
  </connectionStrings>

如果Web.Release.config被使用。
  <connectionStrings>
    <add name="Foo" connectionString="ServerConnectionString"
         xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
  </connectionStrings>

当您以发布配置构建项目时,Web.config将具有值为ServerConnectionStringFoo连接字符串。
此外,我建议您使用SlowCheetah包,它允许您根据构建配置转换您的app.config或任何其他基于XML的文件。
正如我在评论中提到的,如果出于某种原因您不想依赖于构建配置,那么您可以向您的依赖注入框架(Unity、Ninject等)请求正确的参数。以下是Ninject的示例:
Bind<IFoo>().To<Foo>().WithConstructorArgument("bar", 
     context => IsLocalMachine ? "DefaultConnection" : "ServerConnectionString");

当Foo被实例化时(在您的情况下是DbContext),适当的字符串将传递给构造函数:
public class Foo : FooBase, IFoo
{
    public Foo(string bar) : base(bar)
    {            
    }
}

1
@AdrianKsiężarczyk 顺便说一下,如果您想根据机器名称而不是构建配置获得不同的字符串,那么可以通过依赖注入框架轻松解决(适当的连接字符串名称将被注入到构造函数中)。 - Sergey Berezovskiy
1
@AdrianKsiężarczyk 我为您添加了 DI 示例 :) - Sergey Berezovskiy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接