我有一个类似
的对象public class Foo
{
public string PassChoiseInfo { get; set; }
public string FailChoiceInfo { get; set; }
public string NAChoiceInfo { get; set; }
}
我有一个方法,用适当的数据返回对象,如下所示:
public Foo GetInfo(TestName testNames)
{
int testNameId = testNames.TestId;
Foo foo = new Foo();
switch (testNameId)
{
case 3:
var passRecord = testNames.TestItems.Where(ex => ex.TestNamesId == 3 && ex.TestItemName == "Pass")
.Select(r => new
{
r.TestItemId,
r.TestItemName,
r.TestItemDirectory
}).FirstOrDefault();
foo.PassChoiseInfo = $"{passRecord.TestItemId},{passRecord.TestItemName},{passRecord.TestItemDirectory}";
var failRecord = testNames.TestItems.Where(ex => ex.TestNamesId == 3 && ex.TestItemName == "Fail")
.Select(r => new
{
r.TestItemId,
r.TestItemName,
r.TestItemDirectory
}).FirstOrDefault();
foo.FailChoiceInfo = $"{failRecord.TestItemId},{failRecord.TestItemName},{failRecord.TestItemDirectory}";
var naRecord = testNames.TestItems.Where(ex => ex.TestNamesId == 3 && ex.TestItemName == "N/A")
.Select(r => new
{
r.TestItemId,
r.TestItemName,
r.TestItemDirectory
}).FirstOrDefault();
foo.NAChoiceInfo = $"{naRecord.TestItemId},{naRecord.TestItemName},{naRecord.TestItemDirectory}";
break;
case 4:
break;
case 5:
break;
case 7:
break;
//6 more cases
}
return foo;
}
}
正如您在我的GeTInfo
方法中所看到的,我继续使用相同的代码来更改.where
条件,我必须在很多情况下执行此操作。有人能告诉我实现这一目标的最佳方法是什么?
答案 0 :(得分:2)
我将查询提取到另一个返回所需描述字符串的方法。
public Foo GetInfo(TestName testNames)
{
string GetItemDescriptionShortcut(string testItemName)
{
return this.GetItemDescription(testNames, testItemName);
}
Foo foo = new Foo
{
PassChoiseInfo = GetItemDescriptionShortcut("Pass"),
FailChoiceInfo = GetItemDescriptionShortcut("Fail"),
NAChoiceInfo = GetItemDescriptionShortcut("N/A")
}
return foo;
}
private string GetItemDescription (TestName testNames, string testItemName)
{
var item = testNames.TestItems
.Where(ex => ex.TestNamesId == testNames.TestId && ex.TestItemName == testItemName)
.Select(r => new
{
r.TestItemId,
r.TestItemName,
r.TestItemDirectory
}).FirstOrDefault();
if (item == null) return null; // or empty string
return $"{item.TestItemId},{item.TestItemName},{item.TestItemDirectory}";
}
答案 1 :(得分:1)
您可以解决的一点重复代码是传递给Select()
的代理:
r => new
{
r.TestItemId,
r.TestItemName,
r.TestItemDirectory
}
目前,您正在制作此委托的三个匿名实例。相反,您可以创建一次委托并将其另存为Func<TypeOfR, Foo>
类型的局部变量,然后将该变量传递给Select()
:
Func<TypeOfR, Foo> select = r => new { ... };
// ...
...Select(select).FirstOrDefault();
再远一点,你的三次重复中唯一真正改变的是Where
子句。因此,您可以定义一个执行样板的函数,并将Where
子句或委托作为形式参数:
Foo GetObject(TestName testNames, Func<TypeOfEx, bool> predicate)
{
return testNames.TestItems
.Where(predicate)
.Select(r => new
{
r.TestItemId,
r.TestItemName,
r.TestItemDirectory
}).FirstOrDefault();
}
然后这样称呼:
var failRecord = GetObject(testNames, ex => ex.TestNamesId == 3 && ex.TestItemName == "Fail");
请为方法命名比GetObject
更合适的方法,但如果不了解更多背景信息,我就无法建议一个好名字:)
现在,如果您的Where
表达式始终采用相同的格式,您可以再向前迈一步,将TestNamesId
和TestItemName
应作为参数保存的值传递给您的方法代表:
Foo GetObject(TestName testNames, string id, string name)
{
return testNames.TestItems
.Where(ex => ex.TestNamesId == id && ex.TestItemName == name)
.Select(r => new
{
r.TestItemId,
r.TestItemName,
r.TestItemDirectory
}).FirstOrDefault();
}
答案 2 :(得分:0)
它是委托风格的解决方案。你可以将它重构为纯方法。
switch
也可以删除NullPointerException
语句并使代码更通用。
答案 3 :(得分:-1)
您应该创建一个包含重复代码的辅助函数。
private static dynamic GetDataWithName(TestName testNames, string name)
{
return testNames.TestItems.Where(ex => ex.TestNamesId == testNames.TestId && ex.TestItemName == name)
.Select(r => new
{
r.TestItemId,
r.TestItemName,
r.TestItemDirectory
}).FirstOrDefault();
}
public Foo GetInfo(TestName testNames)
{
int testNameId = testNames.TestId;
Foo foo = new Foo();
switch (testNameId)
{
case 3:
var passRecord = GetDataWithName(testNames, "PASS");
foo.PassChoiseInfo = $"{passRecord.TestItemId},{passRecord.TestItemName},{passRecord.TestItemDirectory}";
var failRecord = GetDataWithName(testNames, "FAIL");
foo.FailChoiceInfo = $"{failRecord.TestItemId},{failRecord.TestItemName},{failRecord.TestItemDirectory}";
var naRecord = GetDataWithName(testNames, "N/A");
foo.NAChoiceInfo = $"{naRecord.TestItemId},{naRecord.TestItemName},{naRecord.TestItemDirectory}";
break;
case 4:
break;
case 5:
break;
case 7:
break;
//6 more cases
}
return foo;
}
}