(NET) 2002

My first generic function in VB.NET

Как написать свой Дженерик на VB? Этого я пока не знаю и пытаюсь в данный момент этому научится.

Обычно все языки поддерживают макроопределения, которые достаточно ПРОСТО позволяют применить ОДИН алгоритм в нескольким типам данных, без потери контроля типов.

Например берем вот этот алгоритм - он просто работает с разными свойствами одного и того же обьекта. И соответственно имеет чуть-чуть разные названия.

00001:     'Рекурсивный обход дерева в поисках нужного тега
00002:     Private Function GetNodesForTag(ByVal StartNode As system.web.SiteMapNode, ByVal TableIndex As Integer) As System.Web.SiteMapNode
00003:         If StartNode.ResourceKey = TableIndex Then Return StartNode
00004:         If StartNode.ChildNodes IsNot Nothing Then
00005:             For Each X As system.web.SiteMapNode In StartNode.ChildNodes
00006:                 If X.ResourceKey = TableIndex Then
00007:                     Return X
00008:                 Else
00009:                     'обход в глубину - сразу же проверяем его дочек
00010:                     Dim Y As system.web.SiteMapNode = GetNodesForTag(X, TableIndex)
00011:                     If Y IsNot Nothing Then Return Y
00012:                 End If
00013:             Next
00014:         End If
00015:     End Function
и берем второй ПОХОЖИЙ код.
00001:     'Рекурсивный обход дерева в поисках нужного URL
00002:     Private Function GetNodesForURL(ByVal StartNode As system.web.SiteMapNode, ByVal URL As String) As System.Web.SiteMapNode
00003:         If StartNode.URL = URL Then Return StartNode
00004:         If StartNode.ChildNodes IsNot Nothing Then
00005:             For Each X As system.web.SiteMapNode In StartNode.ChildNodes
00006:                 If X.Url = URL Then
00007:                     Return X
00008:                 Else
00009:                     'обход в глубину - сразу же проверяем его дочек
00010:                     Dim Y As system.web.SiteMapNode = GetNodesForURL(X, URL)
00011:                     If Y IsNot Nothing Then Return Y
00012:                 End If
00013:             Next
00014:         End If
00015:     End Function
Обычно, так было всегда - даже ТРИДЦАТЬ лет назад, этот единый алгоритм превращатся в ОДИН кусок кода вот таким образом.
1.Делается вот такой макрос.
00000: Search Macro  &Pref , &Property , &Type 
00001:    'Рекурсивный обход дерева в поисках нужного &Type
00002:    Private Function GetNodesFor&Pref(ByVal StartNode As System.Web.SiteMapNode, ByVal URL As &Type) As System.Web.SiteMapNode
00003:         If StartNode.&Property= URL Then Return StartNode
00004:         If StartNode.ChildNodes IsNot Nothing Then
00005:             For Each X As System.Web.SiteMapNode In StartNode.ChildNodes
00006:                 If X.&Property = URL Then
00007:                     Return X
00008:                 Else
00009:                     'обход в глубину - сразу же проверяем его дочек
00010:                     Dim Y As system.web.SiteMapNode = GetNodesFor&Pref(X, URL)
00011:                     If Y IsNot Nothing Then Return Y
00012:                 End If
00013:             Next
00014:         End If
00015:     End Function
00000: End  Macro 
2.Вот таким его вызовом порождается обе указанные функции. А заодно еще десяток (свойства которых есть у обьекта StartNode):
Search "Tag", "ResourceKey",  "Integer"
Search "URL", "URL",  "String"
Таким же образом мы всегда могли поступить. Всегда, пока не появилось MS со своим компилятором с C#.NET и VB.NET. Вот в этих двух фрагментах моего кода - отличия более тонкие. И делегатами их не разрешить.
00001:     Shared Sub FillTree(ByVal CurrentTovar As WorkingTovar, ByRef Tv1 As System.Web.UI.WebControls.TreeView)
00002:         For i As Integer = 0 To CurrentTovar.PriceDS.MyBlock.Count - 1
00003:             Dim X As New TreeNode
00004:             X.SelectAction = TreeNodeSelectAction.Expand
00005:             X.Text = CurrentTovar.PriceDS.MyBlock(i).Gname
00006:             X.Value = "MyBlock_i=" & CurrentTovar.PriceDS.MyBlock(i).i.ToString
00007:             For j As Integer = 0 To CurrentTovar.PriceDS.MyFieldsList.Count - 1
00008:                 If CurrentTovar.PriceDS.MyFieldsList(j).ToBlock = CurrentTovar.PriceDS.MyBlock(i).i Then
00009:                     For k As Integer = 0 To CurrentTovar.PriceDS.MyFields.Count - 1
00010:                         If CurrentTovar.PriceDS.MyFields(k).i = CurrentTovar.PriceDS.MyFieldsList(j).ToFields Then
00011:                             Dim Y As New TreeNode
00012:                             Y.SelectAction = TreeNodeSelectAction.Expand
00013:                             Y.Text = CurrentTovar.PriceDS.MyFields(k).Fname & " : "
00014:                             For l As Integer = 0 To CurrentTovar.PriceDS.MyValueList.Count - 1
00015:                                 If CurrentTovar.PriceDS.MyValueList(l).ToFields = CurrentTovar.PriceDS.MyFieldsList(j).ToFields Then
00016:                                     For m As Integer = 0 To CurrentTovar.PriceDS.MyValue.Count - 1
00017:                                         If CurrentTovar.PriceDS.MyValue(m).i = CurrentTovar.PriceDS.MyValueList(l).ToValue Then
00018:                                             Try
00019:                                                 Y.Text &= CurrentTovar.PriceDS.MyValue(m).VValue
00020:                                                 Y.Value = "MyBlock_i=" & CurrentTovar.PriceDS.MyBlock(i).i.ToString & ",MyFields_i=" & CurrentTovar.PriceDS.MyFields(k).i.ToString & ",MyValue_I=" & CurrentTovar.PriceDS.MyValue(m).i.ToString
00021:                                             Catch n As System.Data.StrongTypingException
00022:                                             End Try
00023:                                         End If
00024:                                     Next
00025:                                 End If
00026:                             Next
00027:                             X.ChildNodes.Add(Y)
00028:                         End If
00029:                     Next
00030:                 End If
00031:             Next
00032:             Tv1.Nodes.Add(X)
00033:         Next
00034:     End Sub
00001:     Shared Sub FillTree(ByVal CurrentTovar As WorkingTovar, ByRef Tv1 As System.Windows.Forms.TreeView)
00002:         For i As Integer = 0 To CurrentTovar.PriceDS.MyBlock.Count - 1
00003:             Dim X As New System.Windows.Forms.TreeNode
00004:             X.Text = CurrentTovar.PriceDS.MyBlock(i).Gname
00005:             X.Name = "MyBlock_i=" & CurrentTovar.PriceDS.MyBlock(i).i.ToString
00006:             For j As Integer = 0 To CurrentTovar.PriceDS.MyFieldsList.Count - 1
00007:                 If CurrentTovar.PriceDS.MyFieldsList(j).ToBlock = CurrentTovar.PriceDS.MyBlock(i).i Then
00008:                     For k As Integer = 0 To CurrentTovar.PriceDS.MyFields.Count - 1
00009:                         If CurrentTovar.PriceDS.MyFields(k).i = CurrentTovar.PriceDS.MyFieldsList(j).ToFields Then
00010:                             Dim Y As New System.Windows.Forms.TreeNode
00011:                             Y.Text = CurrentTovar.PriceDS.MyFields(k).Fname & " : "
00012:                             For l As Integer = 0 To CurrentTovar.PriceDS.MyValueList.Count - 1
00013:                                 If CurrentTovar.PriceDS.MyValueList(l).ToFields = CurrentTovar.PriceDS.MyFieldsList(j).ToFields Then
00014:                                     For m As Integer = 0 To CurrentTovar.PriceDS.MyValue.Count - 1
00015:                                         If CurrentTovar.PriceDS.MyValue(m).i = CurrentTovar.PriceDS.MyValueList(l).ToValue Then
00016:                                             Try
00017:                                                 Y.Text &= CurrentTovar.PriceDS.MyValue(m).VValue
00018:                                                 Y.Name = "MyBlock_i=" & CurrentTovar.PriceDS.MyBlock(i).i.ToString & ",MyFields_i=" & CurrentTovar.PriceDS.MyFields(k).i.ToString & ",MyValue_I=" & CurrentTovar.PriceDS.MyValue(m).i.ToString
00019:                                             Catch n As System.Data.StrongTypingException
00020:                                             End Try
00021:                                         End If
00022:                                     Next
00023:                                 End If
00024:                             Next
00025:                             X.Nodes.Add(Y)
00026:                         End If
00027:                     Next
00028:                 End If
00029:             Next
00030:             Tv1.Nodes.Add(X)
00031:         Next
00032:     End Sub
Здесь присутствует и две лишние строчки кода, и разный тип параметров и чуть чуть различающийся ключик.

Но алгоритм-то явно один, хоть и с крошечной модификацией.


Не могу понять как из этих двух кусков кода сделать ДЕЙСТВИТЕЛЬНО ОДНУ программу. Ведь архи-важный принцип программирования - ПОВТОРНОЕ ИСПОЛЬЗОВАНИЕ КОДА. Не спорю, возможно это делается. Но этот принцип нарушается в MS-технологиях ПОВСЕМЕСТНО:

Хотя, не исключено, что я просто не уловил задумки - как именно эти два фрагмента кода свести В ОДИН...



Comments ( )
Link to this page: //www.vb-net.com/Dotnet/Generic/Index.htm
< THANKS ME>