VB.NET - 滥用实例变量? [英] VB.NET - Misusing instance variables?

查看:129
本文介绍了VB.NET - 滥用实例变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请看下面的代码:

    Public Class A
    Public person1 As Person
End Class

Public Class B
    Inherits A

    Public Function CheckGender() As Boolean
        If person1._Gender = "M" Then
            CheckGender = True
        End If
    End Function

End Class

Public Class C
    Inherits B
    Public Function CheckAge() As Boolean
        If person1._Age > 30 Then
            CheckAge = True
        End If
    End Function

End Class

Public Class D
    Inherits C

    Public Sub SomeMethod()
        Dim list As List(Of Person) = New List(Of Person)
        Dim p1 As New Person("Ian", "M", 31)
        Dim p2 As New Person("Susan", "F", 20)
        Dim p3 As New Person("Mark", "M", 22)
        list.Add(p1)
        list.Add(p2)
        list.Add(p3)

        For Each Person As Person In list
            person1 = Person
            If CheckAge() And CheckGender() Then
                'Do something
            End If
        Next
    End Sub

    Public Shared Sub Main()
        Dim d As New D
        d.SomeMethod()
    End Sub

End Class

Public Class Person
    Public _Name As String
    Public _Gender As String
    Public _Age As String
    Public Sub New(ByVal Name As String, ByVal Gender As String, ByVal Age As Integer)
        _Name = Name
        _Gender = Gender
        _Age = Age
    End Sub
End Class

c.SomeMethod 通过三个人循环并执行两个检查: b.CheckGender c.CheckAge CheckGender CheckAge 使用超类 A 中的实例变量。

c.SomeMethod loops through three persons and does two checks: b.CheckGender and c.CheckAge. CheckGender and CheckAge use an instance variable from the superclass A.

现场环境中的代码每天在数据库中循环100,000条记录,并删除那些 CheckGender CheckAge 都是真的。 在这种情况下使用实例变量是不是很糟糕的设计选择?我一直被教导使用局部变量。我希望将 Person 对象传递给 CheckGender CheckAge 每个循环。还是真的没关系?

The code in the live environment loops through 100,000 records daily in a database and deletes those where CheckGender and CheckAge are both true. Is it a bad design choice to use instance variables in this scenario? I was always taught to use local variables. I would expect the Person object to be passed to CheckGender and CheckAge on each loop. Or does it really not matter?

请注意,上面的代码是一个假设的例子。 CheckGender CheckAge 是实际应用中的复杂功能。

Please note that the above code is a hypothetical example. CheckGender and CheckAge are complex functions in the actual application.

推荐答案

只要 CheckGender CheckAge 不访问层次结构中的任何私有,受保护或内部成员,并且是公共函数,并且对于任何实例,它们的逻辑是相同的, A B C ,在另一个类中使用这些方法是一个更好的设计。如果可能,使它们静止。您可以让他们接受最常见的课程实施(例如, A ),允许检查年龄或性别。从您的代码中,您甚至可以通过 Person 属性,而不是使用任何 A B C 类。

As long as CheckGender and CheckAge are not accessing any private, protected or internal member of the classes in hierarchy, and are public functions, and their logic is the same for any instance, being A, B, or C, it is a better design to have these methods in another class. Make them static if possible. You can have them accept the most general implementation of your classes (A for instance) that allows checking either the age or gender. Taken from your code, you can even pass the Person property instead of using any of the A, B and C classes.

在上述情况下使用继承只要您需要执行以下任何或全部操作即可使用此类逻辑:

Use of inheritance in the above case and such logic is permitted though, as long as you need to do any or all of the following:


  • 符合特定界面或基础类 A B C 类必须实现/扩展,该接口或基类提供了 CheckGender CheckAge 方法。如果您将对象传递到第三方API,则可以是唯一的解决方案,该API接受基类/接口作为参数,并在内部调用检查方法。

  • Conform to a specific interface or base class, that A, B and C classes have to implement/extend, and that interface or base class provides the CheckGender and CheckAge methods. This can be the only solution if you pass your objects to 3rd party API, that accepts the base class/interface as an argument and internally calls the check methods.

这里是C#中的示例:

public static class CheckUtil
{
    public static bool CheckAgeOfPerson(Person p)
    {
        return p.Age > 30;
    }
    public static bool CheckAgeOfObject(A obj)
    {
        // NOTE: obj.person1 must be accessible - by being either public or internal.
        // If this class is in another assembly, internal is not useful
        return CheckAgeOfPerson(obj.person1);
    }
}

A objA = ...;
B objB = ...;
C objC = ...;

CheckUtil.CheckAgeOfObject(objA);
CheckUtil.CheckAgeOfObject(objB);
CheckUtil.CheckAgeOfObject(objC);

CheckUtil.CheckAgeOfPerson(objA.person1);
CheckUtil.CheckAgeOfPerson(objB.person1);
CheckUtil.CheckAgeOfPerson(objC.person1);




  • 为类提供具体的实现如果在 CheckAge 中为 A 的实例提供了一些逻辑,但对<$ c的实例完全不同的验证$ c> B ,或 C 中现有和一些新逻辑的组合,则继承是您的朋友。但是,如果是这样,我更愿意将 CheckGender CheckAge 接口并通过接口。这样,继承是有效的,但不是强制的,只要界面满意。

    • Provide specific implementation to the classes. If you have to some logic in CheckAge for instances of A, but either completely different validation for instances of B, or a combination of the existing and some new logic in C, then inheritance is your friend. Still, if that is the case, I'd prefer exposing the CheckGender and CheckAge to interface and call them via the interface. That way, inheritance is valid, but not mandatory, as long the interface is satisfied.
    • 这里是C#中的一个例子: p>

      here is an example in C#:

      public interface IGenderCheckable
      {
          bool CheckGender();
      }
      
      public interface IAgeCheckable
      {
          bool CheckAge();
      }
      
      public class A : IAgeCheckable, IGenderCheckable
      {
          public virtual bool CheckGender()
          {
              return this.person1.Gender.Equals("M");
          }
      
          public virtual bool CheckAge()
          {
              return this.person1.Age > 30;
          }
      }
      
      public class B : A
      {
           public override bool CheckAge()
           {
                // combine custom logic with new logic
                return this.person1.Age < 0 || base.CheckAge();
           }
      }
      

      对于复杂场景,两者的组合方法也可能被使用(当然比年龄和性别检查要复杂得多):

      For complex scenarios, a combination of both approaches might be also used (of course for far more complex cases than age and gender checks):

      public class A : IAgeCheckable, IGenderCheckable
      {
          ...
      }
      
      public static class CheckUtil
      {
          public static bool CheckAge(IAgeCheckable obj)
          {
              return obj.CheckAge();
          }
          public static bool CheckGender(IGenderCheckable)
          {
              return obj.CheckGender();
          }
      }
      






      关于实例变量与局部变量的使用 - 在.NET中使用实例变量的性能有一个缺点,特别是当它们是值类型时。例如,使用 int _someIntMember 的本地成员转换为 this._someIntMember - 这又将堆调用获取对象,然后访问其 _someIntMember 成员。将成员作为局部变量,将其值放在堆栈中,并从其中读取,而不需要通过堆的不必要的往返。此外,堆栈比堆快。


      About usage of instance variables vs local variables - there is a drawback in performance of using instance variables in .NET especially when they are value types. Use of local member that is int _someIntMember for example gets translated to this._someIntMember - which in turn calls the heap to get the this object, and then accesses its _someIntMember member. Having the member as a local variable, puts its value in the stack, and reads it from there without the unnecessary roundtrip trough the heap. Moreover, the stack is faster than the heap.

      但是,我不能说太多的堆使用是滥用它,也不是在使用太多时滥用局部变量。这取决于所需的性能和代码的复杂性。有时局部变量使代码更易于阅读,但是如果太多,你可以很容易地忘记每一个是什么(这可能比疏忽的性能增益更严重)。所以这是一个风格和必要性的问题。

      However, I cannot say whether too much heap usage is an abuse of it, neither a misuse of local variables when they are used too much. This depends on the performance needed, and the complexity of code. Sometimes local variables make the code more-readable, but if too many, you could easily forget what each one was (and that can be more serious issue than the negligent performance gain). So it is a matter of style and necessity.

      这篇关于VB.NET - 滥用实例变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆