从表中检索查找代码值时,有些人会这样做......
Dim dtLookupCode As New LookupCodeDataTable()
Dim taLookupCode AS New LookupCodeTableAdapter()
Dim strDescription As String
dtLookupCode = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL")
strDescription = dtLookupCode.Item(0).Meaning
...但是,我也看到过这样的事情已经“链接”了......
strDescription = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL").Item(0).Meaning
...由于表适配器知道结果集的结构是什么样的,因此首先绕过了查找代码数据表。
使用“chained”方法是否可以节省创建数据表对象的开销,还是有效地创建它以便正确处理.Item(0).Meaning语句?
答案 0 :(得分:5)
这两行会编译成同样的东西。我会选择哪一个更容易阅读。内联通常指的是a bit different。
答案 1 :(得分:4)
从“内联”部分来看,实际上,这两组代码不会编译成同一个东西。问题在于:
Dim dtLookupCode As New LookupCodeDataTable()
Dim taLookupCode AS New LookupCodeTableAdapter()
在VB中,这将使用适当命名的引用创建新对象。其次是:
dtLookupCode = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL")
我们立即用新对象替换原始dtLookupCode
引用,这会创建要收集的垃圾(RAM中无法访问的对象)。
因此,在确切的原始场景中,所谓的“内联”技术是技术上,性能更高。 (但是,你不太可能在这个小例子中看到这种差异。)
代码基本相同的地方是原始样本如下所示:
Dim taLookupCode AS New LookupCodeTableAdapter
Dim dtLookupCode As LookupCodeDataTable
Dim strDescription As String
dtLookupCode = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL")
strDescription = dtLookupCode.Item(0).Meaning
在这个世界中,我们只有现有的引用,而不是创建垃圾对象。为了便于阅读,我对这些陈述进行了重新排序,但要点是相同的。此外,您可以使用类似的内容轻松地对引用进行单行初始化,并具有相同的基本概念:
Dim taLookupCode AS New LookupCodeTableAdapter
Dim dtLookupCode As LookupCodeDataTable = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL")
Dim strDescription As String = dtLookupCode.Item(0).Meaning
答案 2 :(得分:2)
是的,不要说“内联”,因为这意味着其他语言中的特定内容。最有可能的是性能差异为零或者小到无关紧要,这只是一个偏好问题。您是想在单独的语句中写出来以使其更清晰,或者将其全部写在一行上以便更快地输入它?
答案 3 :(得分:2)
通常它只会使代码的可读性降低。
通常,当人们使用这种“内联”(即链接)时,他们将多次重新访问类的属性或字段,而不是只获取一次并存储在局部变量中。这通常是一个坏主意,因为通常不知道该字段或属性是如何返回的。例如,它可以每次计算,或者可以计算一次并私下存储在类中。
这是两个插图。第一个片段是要避免的:
if (ConfigurationManager.AppSettings("ConnectionString") == null)
{
throw new MissingConfigSettingException("ConnectionString");
}
string connectionString = ConfigurationManager.AppSettings("ConnectionString");
第二个是可取的:
string connectionString = ConfigurationManager.AppSettings("ConnectionString")
if (connectionString == null)
{
throw new MissingConfigSettingException("ConnectionString");
}
这里的问题是AppSettings()实际上必须在每次检索到值时取消装箱AppSettings集合:
// Disassembled AppSettings member of ConfigurationManager
public static NameValueCollection AppSettings
{
get
{
object section = GetSection("appSettings");
if ((section == null) || !(section is NameValueCollection))
{
throw new
ConfigurationErrorsException(SR.GetString("Config_appsettings_declaration_invalid"));
}
return (NameValueCollection) section;
}
}
答案 4 :(得分:1)
如果你想看到中间状态,并且单步进入阶段,调试后者会更难。
我会考虑这里使用的屏幕不动产的可读性,因为性能很好。
答案 5 :(得分:1)
我称之为链接。
你问的是错误的问题。
您需要问的是:哪个更具可读性?
如果链接使代码更容易阅读和理解,那么就去做吧。
但是,如果它混淆了,那就不要。
任何性能优化都是不存在的。不要优化代码,优化算法。
所以,如果你打算调用Item(1)和Item(2),那么通过链接,你将一遍又一遍地创建同一个对象,这是一个糟糕的算法。
在这种情况下,第一个选项更好,因为您不需要每次都重新创建适配器。
答案 6 :(得分:1)
反对'链接'的一个原因是Law of Demeter,这表明您的代码在LookupCodeDataTable发生变化时很脆弱。
您应该添加如下函数:
function getMeaning( lookupCode as LookupCodeDataTable)
getMeaning=lookupCode.Item(0).Meaning
end function
并将其称为:
strDescription=getMeaning(taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL"))
现在可以在许多其他地方调用getMeaning(),如果LookupCodeDataTable发生变化,那么你只需要更改getMeaning()来修复它。
答案 7 :(得分:0)
结构仍然是创建的,你只是没有它的参考。
答案 8 :(得分:0)
此:
dtLookupCode = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL")
strDescription = dtLookupCode.Item(0).Meaning
和此:
strDescription = taLookupCode.GetDataByCodeAndValue("EmpStatus", "FULL").Item(0).Meaning
完全等效。
在第一个示例中,您有一个显式的临时引用(dtLookupTable)。在第二个示例中,临时引用是隐式的。在幕后,编译器几乎肯定会为这两者创建相同的代码。即使没有发出相同的代码,额外的临时引用也非常便宜。
但是,我不确定这一行:
Dim dtLookupCode As New LookupCodeDataTable()
效率很高。在我看来,这会创建一个新的LookupCodeDataTable
,然后在后面的语句中覆盖变量时将其丢弃。我不用VB编程,但我希望这行应该是:
Dim dtLookupCode As LookupCodeDataTable
引用很便宜(可能是免费的),但构建额外的查找表可能不是。
答案 9 :(得分:0)
除非您需要通过引用返回的对象,否则它是相同的 taLookupCode.GetDataByCodeAndValue(“EmpStatus”,“FULL”)或项目(0) 多次。否则,你不知道这个函数的运行时是log(n)还是n,所以为了最好的选择,我会为它分配一个引用。
答案 10 :(得分:0)
除了可维护性之外,这是避免链接的另一个原因:错误检查。
是的,您可以将整个事物包装在try / catch中,并捕获链的任何部分可能抛出的每个异常。
但是如果你想在没有try / catch的情况下验证调用之间的结果,你必须将事情分开。例如:
如果您正在进行链接,则无法在没有try / catch的情况下检查这些值。