参数是否可选,具体取决于之前的参数

时间:2018-01-30 15:01:06

标签: c# .net

我有两种方法:

Foo(int a, bool useDb)
Foo(int a, bool useDb, DbContext dbContext)

有没有办法将它作为一种方法,用这些规则?
如果useDb为真,则dbContext是强制性的 如果useDb为false dbContext是可选的

修改

只是一个编辑来澄清,我正在尝试做什么: 在商家/服务层中,我使用方法ItemService GetItemStatus。它连接到数据库,获取数据并计算状态。

没有什么特别的。它创建了一个DbContext(EF6.0),完成并处理它。标准。但是如果我想将GetItemStatus用作不同事务的一部分呢?哈!?我需要在内部传递DbContext并且不要显然处理它。我创造了这样的东西:

    public ItemStatus GetItemStatus(int itemId, OfficeContext fni = null)
    {
        bool shouldBeDisposed = (fni == null) ? true : false;
        if (shouldBeDisposed) fni = ContextFactory.CreateOfficeContext();

        try
        {

            Do the stuff...

        }
        finally
        {
            if (shouldBeDisposed) fni?.Dispose();
        }

        return ...
    }

但现在我有点害怕,因为如果有人打电话:

GetItemStatus(123456);

......他忘了添加DbContext。我不确定他是否真的意味着它。 Altoguh不应该那么糟糕。他将创造新的并处理它。

但我正在考虑最好的方法,以确保开发人员不会犯错误。 "万无一失"方式。

3 个答案:

答案 0 :(得分:10)

无法强制执行情境可选参数。

您仍然可以将其作为可选参数,然后在未提供所需参数的情况下手动抛出异常。

public void Foo(int a, bool useDB, DbContext dbContext = null)
{
    if(useDB && dbContext == null)
    {
        throw new Exception("DB context must be supplied!");
    }

    //...
}

但是,这会在运行时导致异常,并且不会在编译时发出警告。您最终必须修复以前省略的db上下文,这不是首选方法。

我想知道useDB布尔值的需要是什么。您已经可以从是否传递上下文得出它:

public void Foo(int a, DbContext dbContext)
{
    //you already know useDB == true
}

public void Foo(int a)
{
    //you already know useDB == false
}

这也可以通过使dbcontext成为可选参数来放入单个方法:

public void Foo(int a, DbContext dbContext = null)
{
    bool useDB = (dbContext != null);
}

这似乎是一种更清洁的方法。您省略了一个冗余参数(useDB),这反过来又放弃了强制执行可选参数的需要。
无论谁使用该方法,只需要提供db上下文,如果他们想要使用它。

答案 1 :(得分:3)

在C#中无法使用单个函数签名。最接近你可以实现的是重载

public Foo(int a) { Foo(a, false, null); }
public Foo(int a, DbContext dbContext){ Foo(a, true, dbContext); }
private Foo(int a, bool useDb, DbContext dbContext){ ... }

所有参数的重载都可以是私有的,因此不会使用无效参数调用它。

答案 2 :(得分:1)

听起来这只是你如何做到的事情。

这将是一个解决方案:

Public void Foo(int a, bool useDB, DbContext dbContext)
{
   if(useDb)
   {
       //use the database
   }
   else
   {
      //do whatever you would otherwise do.
   }
}

然后,当你去调用方法时,这里有两个选项:

Foo(1, true, db); //calls Foo with useDB and a dbContext

Foo(1, false, null); //calls Foo with useDB false and null dbContext