C# 参数是否可选,取决于以前的参数
我有两种方法:C# 参数是否可选,取决于以前的参数,c#,.net,C#,.net,我有两种方法: Foo(int a, bool useDb) Foo(int a, bool useDb, DbContext dbContext) 有没有一种方法可以将其作为一种方法,使用这些规则? 如果useDb为真,则dbContext是必需的 如果useDb为false,则dbContext是可选的 编辑: 只是为了澄清一下,我想做的是: 在业务/服务层,我有ItemService方法GetItemStatus。它连接到数据库,获取数据并计算状态 没什么特别的。它创建了一个DbCont
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。我不确定他是不是真的这么想。虽然不应该那么糟糕。他将创建一个新的并处理它
但我在想最好的办法,以确保开发者不会犯错误。“万无一失”的方法。听起来这只是你如何做的问题
这将是一个解决方案:
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
在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){ ... }
包含所有参数的重载可以是私有的,因此不会使用无效参数调用它。无法强制执行情景可选参数
您仍然可以将其设置为可选参数,然后在未提供所需参数的情况下手动引发异常
public void Foo(int a, bool useDB, DbContext dbContext = null)
{
if(useDB && dbContext == null)
{
throw new Exception("DB context must be supplied!");
}
//...
}
但是,这将在运行时导致异常,并且不会在编译时警告您。您将不得不修复之前省略的db上下文,这不是首选方法
我想知道对useDB
boolean的需求是什么。您已经可以从是否传递了上下文中得出:
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上下文就可以了。您还可以添加额外的检查,以确保如果useDB为true,dbContext不会像我之前评论的那样为null。我编辑了我的问题useDB
是一个参数,用于双重检查开发人员是否知道自己在做什么。闻起来了吗?看看我的编辑,你试图解决一个问题,因为你认为开发人员不会是白痴。这不是做这件事的方法。要么自己创建上下文,甚至不要担心他们试图传递上下文。或者只允许他们传递上下文,如果他们搞砸了,则返回null。他们的查询结果为空将非常明确地告诉他们,他们做错了什么。你也可以给他们一个错误。你试图这样做的方式是错误的做法。我想你根本不需要useDb。如果调用者认为它需要提供db,那么它无论如何都会提供。Robert C Martin在他的《干净代码》一书中提到了这一点。让布尔参数声明您正在调用的方法执行多项操作。Martin Fowler有一篇关于这个主题的有趣文章,与其使用标志,不如使用一个命名良好的方法@我编辑了我的问题。你认为我应该有两个功能吗GetItemStatus
和GetItemStatusWithContext
?@Marshall-没错,代码更清晰、更清晰。也更容易单独进行单元测试。我编辑了我的问题<不需要代码>useDB
。它是一个参数,用于双重检查开发人员是否知道他/她在做什么。它有味道吗?@Marshall:(1)如果有人忘记添加dbcontext参数,那就是他们的错误。您的布尔参数不会阻止错误的发生。这给每个人都制造了障碍,以防有人忘记了什么。这是一个比解决方案更大的麻烦。(2) (fni==null)?true:false可以缩短为(fni==null)
(3)就个人而言,我会包装该方法。如果需要,外部方法添加上下文,调用内部方法,然后处理上下文(如果是您的)。不管你从哪里得到上下文,内部方法都会处理db。@Marshall:但是在CodeReview.SE:)的新问题中最好有这样的讨论。谢谢,你说得对。也许今天晚些时候我会在CodeReview上发布一个问题