回报会员的好或坏做法

时间:2012-12-28 19:38:38

标签: c# variables methods

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

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

我想指出的一些事情:

  • 我没有选择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.
    */

这样它被标记为只读并确保它从方法中读取正确的值?


更新

我很欣赏答案;但 为什么 是更好的做法?

  • 对安全有益吗?
  • 只是更整洁?
  • 更灵活

是什么使它成为更好的解决方案;这就是我试图理解的。

5 个答案:

答案 0 :(得分:4)

您可以使用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.");
    }
}

答案 1 :(得分:3)

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

为什么DriveName方法会返回任何内容?它是公开使用还是仅用于填充您的NameOfDrive财产?如果它只在课堂内使用,我会把它变成私有和无效。

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

答案 2 :(得分:2)

虽然,这不一定是不好的做法,但它也不好。

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

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

答案 3 :(得分:1)

我会创建一个类(甚至是扩展名)来提取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:"));
    }
} 

答案 4 :(得分:0)

可能更好的做法是使用只读属性,但是懒得加载它。

下面注意,我将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.");
    }
}