.net:如何优化这段代码?

时间:2011-02-13 10:01:35

标签: .net vb.net optimization refactoring

请帮我优化/重构此代码.....

private sub test
        Call PopulateColorsWithMasterIdentity(Colors, Id)
        Call PopulatePartsWithMasterIdentity(Parts, Id)
        Call PopulateSaloonsWithMasterIdentity(Saloons, Id)
End sub

Private Sub PopulateColorsWithMasterIdentity(ByRef MyList As List(Of entclsCriticalPartSetColor), ByVal Id As Integer)

    For index As Byte = 0 To MyList.Count - 1
        MyList.Item(index).CriticalPartsSetId = Id
    Next
End Sub

Private Sub PopulatePartsWithMasterIdentity(ByRef MyList As List(Of entclsCriticalPartSetPart), ByVal Id As Integer)

    For index As Byte = 0 To MyList.Count - 1
        MyList.Item(index).CriticalPartsSetId = Id
    Next
End Sub

Private Sub PopulateSaloonsWithMasterIdentity(ByRef MyList As List(Of entclsCriticalPartSetSaloon), ByVal Id As Integer)

    For index As Byte = 0 To MyList.Count - 1
        MyList.Item(index).CriticalPartsSetId = Id
    Next
End Sub

*的 修改 *

实际上,是否可以使用“多态”?我的意思是,不是有populateXXXWithMasterIdentity的3个不同部分,我可以有一个像这样的PopulateListWithMasterIdentity:

Private Sub PopulateListWithMasterIdentity(MyList As IList(Of entclsCriticalPartsBase), Id As Integer)
    .....
End Sub

谢谢

4 个答案:

答案 0 :(得分:3)

您无法真正优化此代码,但您可以使其更简洁,因为Item属性调用完全是冗余的。

此外,请不要使用Byte类型作为索引变量,这没有任何意义,即使列表永远不会超过255个元素。始终在此使用Integer(或让编译器使用Option Infer On推断您的类型。)

相反,按如下方式编写循环:

For index As Integer = 0 To MyList.Count - 1
    MyList(index).CriticalPartsSetId = Id
Next

答案 1 :(得分:2)

在更新中,您正在改变每个对象;所以它不能比O(n)更好,它已经是。不需要优化。作为一个重构,我会带走ByRef - 你没有使用它。您也可以考虑使用公共基类或接口,然后所有3个都可以共享一个通用方法。在c#术语中:

interface IFoo {
    int CriticalPartsSetId {get;set;}
}
public static void UpdateCriticalPartsSetId<T>(
    IEnumerable<T> items, int criticalPartsSetId)
    where T : IFoo
{
     foreach(var item in items)
        item.CriticalPartsSetId = criticalPartsSetId;
}

答案 2 :(得分:2)

首先,声明一个包含属性CriticalPartsSetId的接口,该属性对于您使用的所有三种类型都是通用的:

Public Interface IHasCriticalPartsSetId
    Property CriticalPartsSetId As Integer
End Interface

确保您的三种不同类型实现此界面。

接下来,编写一个更新CriticalPartsSetId属性的方法:

Sub PopulateId(xs As IEnumerable(Of IHasCriticalPartsSetId), id As Integer)
    For Each x in xs
        x.CriticalPartsSetId = id
    Next
End Sub

现在我不太确定IEnumerable(Of IHasCriticalPartsSetId)是否会按预期工作,或者如果你确实需要使用泛型类型参数约束,如Marc Gravell的答案所示 - 在VB.NET中这将是是:IEnumerable(Of T As IHasCriticalPartsSetId)

另请注意另一个完全不相关的优化:使用For计数器摆脱Byte循环。使用For Each循环可以使代码更易于阅读。 (并且使用Byte类型的计数器变量实际上可能会比使用Integer类型变量的性能更差,因为(IIRC)CLR扩展了Byte - 大小的值到Integer - 将它们放在内部执行堆栈上时的大小值。)

答案 3 :(得分:0)

要回答你的多态性问题,是的,你可以。但你真的不需要。这三个类中的所有三个都共享一个公共属性(CriticalPartsSetId),因此您可以将它放在基类上并让所有类继承它。多态性可以让你在子类上改变一些东西,但在这种情况下,这是不必要的,因为CriticalPartsSetId做同样的事情。

我有点奇怪,你在这里有三个列表是同一件事的所有部分吗?做这样的事情可能更有意义:

Public Class CriticalPartsSet

    Public Property SetId as Integer
    Public Property SetColors as List(of entclsCriticalPartSetColor)
    Public Property SetParts as List(of entclsCriticalPartSetPart)
    Public Property SetSaloons as List(of entclsCriticalPartSetSaloon)

End Class

如果这样做,setId是集合本身的一部分,更改它是一个操作,而不是三个列表上的迭代。您还可以将整个集合及其所有内容作为单个参数传递给需要它的方法,这很方便。 :)

(最后,如上所述,您应该删除ByRef并使用ByVal.ByRef允许您使用完全不同的列表替换列表并让调用者获取新列表,这不是此处的预期行为。您可以修改使用ByVal列表中的内容,以后出现意外奇怪的可能性较小。)