繁体   English   中英

回归会员的好坏做法

[英]Good or Bad Practice for Return Members

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

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

我想指出一些事情:

  • 我没有选择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()私有,并且没有在构造函数中调用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.");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM