返回成员的好与坏实践

本文关键字:成员 返回 | 更新日期: 2023-09-27 17:50:12

我不确定这是否会是无效的做法;或者很好的练习。我不知所措的原因是我应该使用属性而不是局部变量吗?

我的推理和目标;是一个非常基本的检测本地磁盘驱动器。

我想指出一些事情:

  • 我没有选择boolean value,因为我希望能够调用这个类来返回驱动器路径。从方法中检索到的名称;在某些衍生类中可以达到Path Combined

我的例子:

    public class Drive
    {
        // Variable:
        public string nameOfDrive;
        public Drive()
        {
            // Call Method.
            DriveName();
        }
        public string DriveName()
        {
            DriveInfo [] drives = DriveInfo.GetDrives();
            foreach (DriveInfo d in drives)
            {
                // Verify Valid 'C:' is Present.
                if (d.Name == @"C:")
                {
                    // Set Name:
                    nameOfDrive = d.Name;
                    // Return Result.
                    return d.Name;
                }
            }
            // Exception:
            throw new Exception("Unable to locate the C: Drive... Please map the correct drive.");
        }
    }
    /*
     * The above method and class contains a verification
     * for the 'C:' Drive.  Once the items are validated;
     * it will create a return variable for the 'C:'.  
     * Otherwise it will throw an Exception.
    */

现在我不确定什么是更好的做法。我应该使用一个属性而不是public string nameOfDrive。或者我真的离得太远了-这不是返回可以在其他类中使用的值的最佳方式吗?或者直接引用成员变量是不好的做法吗?

第二个例子:

    public class Drive
    {
        private string nameOfDrive;
        public string NameOfDrive
        {
            get { return nameOfDrive; }
        }
        public Drive()
        {
            // Call Method.
            DriveName();
        }
        public string DriveName()
        {
            // Obtain Drive Information:
            DriveInfo [] drives = DriveInfo.GetDrives();
            foreach (DriveInfo d in drives)
            {
                // Verify Valid 'C:' is Present.
                if (d.Name == @"C:")
                {
                    // Set Name:
                    nameOfDrive = d.Name;
                    // Return Result.
                    return d.Name;
                }
            }
            // Exception:
            throw new Exception("Unable to locate the C: Drive... Please map the correct drive.");
        }
    }
    /*
     * The above method and class contains a verification
     * for the 'C:' Drive.  Once the items are validated;
     * it will create a return variable for the 'C:'.  
     * Otherwise it will throw an Exception.
    */

因此,它被标记为只读,并将确保它从方法中读取正确的值?


更新:

我很欣赏你的回答;但是为什么是更好的实践?

  • 是否有利于安全?
  • 整齐?

是什么让它成为一个更好的解决方案?这就是我想理解的。

返回成员的好与坏实践

您可以使用Lazy类来完成此操作。它专门设计用于解决延迟初始化可能需要一些时间来计算的值的问题。你可以给Lazy对象一个方法,用来计算这个值,第一次请求这个值的时候,它会使用这个函数来生成这个值,之后所有的调用都只返回第一个值。它还具有线程安全的优点(无论在生成值之前有多少人请求该值,该函数只会被调用一次,并且它们都等待直到计算值返回)。

public class Drive
{
    private Lazy<string> nameOfDrive = new Lazy<string>(DriveName);
    public string NameOfDrive
    {
        get { return nameOfDrive.Value; }
    }
    private static string DriveName()
    {
        DriveInfo[] drives = DriveInfo.GetDrives();
        foreach (DriveInfo d in drives)
        {
            if (d.Name == @"C:")
                return d.Name;
        }
        throw new Exception("Unable to locate the C: Drive... Please map the correct drive.");
    }
}

我将使用带有私有成员变量的只读属性。这样,如果您在不破坏调用代码的情况下更改查找驱动器号的方式,则更容易更新类。

为什么你的DriveName方法返回任何东西?它是公开使用还是仅用于填充NameOfDrive属性?如果它只在类内部使用,我会将其设置为私有且无效。

编辑:想想看,这似乎也是一种奇怪的方式,不仅检查驱动器的存在,而且检查开头的字母。为什么要求用户的盘符为C: ?用户设置机器的方式应该无关紧要。如果他们愿意,他们应该能够将他们的操作系统驱动器设置为Q:,并且它不应该破坏您的代码。

虽然这不一定是坏习惯,但也不好。

在大多数情况下,当您有一个简单的数据类(通常不涉及实际代码,只是存储一些值的一种方式)时,应该使用字段。如果超出了这个复杂级别,通常应该让类使用属性。几个原因:

  1. 以后从字段转换为属性将打破依赖关系,并要求使用您的类的所有代码重新编译
  2. 属性具有更细粒度的控制。快速浏览一下你的用例,看起来你应该有一个getter,它将自动填充和缓存驱动器号,并将默认setter设置为私有,因此它是只读的
  3. 属性可以是虚拟的。这意味着人们更容易扩展你的类,超出你最初的想象。

我将创建一个类(甚至一个扩展)来提取cdrive。让消费者根据自己的需要抛出错误。

通过创建泛型方法,允许根据情况重用过程,并坚持使用面向对象的原则,将概念隔离为唯一的对象。

void Main()
{
  if (Drive.AcquireCDrive() == null)
      throw new Exception("Unable to locate the C: Drive... Please map the correct drive.");
}
public class Drive
{
    public static DriveInfo AcquireCDrive()
    {
       return DriveInfo.GetDrives()
                       .OfType<DriveInfo>()
                       .Where (drive => drive.IsReady)
                       .FirstOrDefault( drive => drive.Name.Contains(@"C:"));
    }
} 

也许更好的做法是使用只读属性,但是延迟加载。

注意下面,我将DriveName()方法设为私有,并且没有在构造函数中调用DriveName()方法。

public class Drive
{
    private string nameOfDrive = null;
    public string NameOfDrive
    {
        get 
        {
            if (nameOfDrive == null)
                nameOfDrive = DriveName();
            return nameOfDrive; 
        }
    }
    public Drive()
    {    }
    private string DriveName()
    {
        DriveInfo[] drives = DriveInfo.GetDrives();
        foreach (DriveInfo d in drives)
        {
            if (d.Name == @"C:")            
                return d.Name;
        }
        throw new Exception("Unable to locate the C: Drive... Please map the correct drive.");
    }
}