C#从内存使用角度看重复代码行与使用属性

C#从内存使用角度看重复代码行与使用属性,c#,optimization,wmi-query,C#,Optimization,Wmi Query,我想知道,从可维护性和内存影响的角度来看,是否有更好的方法来实现以下代码。看看下面的代码,使用属性会更好吗?我看到很多重复的代码,我想知道最好的方法是什么 public class Win32OperatingSystem { internal ulong BytesToMegaBytes(ulong bytes) { return bytes / (ulong)1024; } public ulong FreePhysicalMemory()

我想知道,从可维护性和内存影响的角度来看,是否有更好的方法来实现以下代码。看看下面的代码,使用属性会更好吗?我看到很多重复的代码,我想知道最好的方法是什么

public class Win32OperatingSystem
{
    internal ulong BytesToMegaBytes(ulong bytes)
    {
        return bytes / (ulong)1024;
    }

    public ulong FreePhysicalMemory()
    {
        ManagementObjectSearcher moSearcher = new ManagementObjectSearcher
            ("SELECT FreePhysicalMemory FROM Win32_OperatingSystem");
        using (var enu = moSearcher.Get().GetEnumerator())
        {
            if (!enu.MoveNext()) return 0;
            return BytesToMegaBytes((ulong)enu.Current["FreePhysicalMemory"]);
        }
    }

    public ulong TotalVirtualMemorySize()
    {
        ManagementObjectSearcher moSearcher = new ManagementObjectSearcher
            ("SELECT TotalVirtualMemorySize FROM Win32_OperatingSystem");
        using (var enu = moSearcher.Get().GetEnumerator())
        {
            if (!enu.MoveNext()) return 0;
            return BytesToMegaBytes((ulong)enu.Current["TotalVirtualMemorySize"]);
        }
    }

    public ulong FreeVirtualMemory()
    {
        ManagementObjectSearcher moSearcher = new ManagementObjectSearcher
            ("SELECT FreeVirtualMemory FROM Win32_OperatingSystem");
        using (var enu = moSearcher.Get().GetEnumerator())
        {
            if (!enu.MoveNext()) return 0;
            return BytesToMegaBytes((ulong)enu.Current["FreeVirtualMemory"]);
        }
    }
} 
与其重复这种方法,不如做一些像

MyMethod(string propertyName)
{
        ManagementObjectSearcher moSearcher = new ManagementObjectSearcher
            ("SELECT " + propertyName + " FROM Win32_OperatingSystem");
        using (var enu = moSearcher.Get().GetEnumerator())
        {
            if (!enu.MoveNext()) return 0;
            return BytesToMegaBytes((ulong)enu.Current[propertyName]);
        }
    }

使用DRY原则会使您的第二个选项更好(忽略本例中缺少SQL参数)。它编写的代码更少,并且易于维护。但是,如果修复代码的开发人员不知道调用此函数的所有位置,则可能会导致错误

我倾向于使用单个私有方法,然后从公共方法调用它

public class Win32OperatingSystem
{
    internal ulong BytesToMegaBytes(ulong bytes)
    {
        return bytes / (ulong)1024;
    }

    public ulong FreePhysicalMemory()
    {
        return GetProperty("FreePhysicalMemory");
    }

    public ulong TotalVirtualMemorySize()
    {
        return GetProperty("TotalVirtualMemorySize");
    }

    public ulong FreeVirtualMemory()
    {
        return GetProperty("FreeVirtualMemory");
    }

    private ulong GetProperty(string propertyName)
    {
        ManagementObjectSearcher moSearcher = new ManagementObjectSearcher
            ("SELECT " + propertyName + " FROM Win32_OperatingSystem");
        using (var enu = moSearcher.Get().GetEnumerator())
        {
            if (!enu.MoveNext()) return 0;
            return BytesToMegaBytes((ulong)enu.Current[propertyName]);
        }
    }
}

当然,这就是干的原理

但是,不要用这个方法替换其他3种方法。让你的新方法私有化(当你使用它时,给它一个更好的名字),让其他3个调用它

public ulong FreePhysicalMemory()
{
    return FindMemoryObject("FreePhysicalMemory");
}
这不仅在可维护性方面更好,而且在可读性方面也更好


至于性能或内存,不要担心。是的,有一个额外的抽象级别,必须调用一个方法(可能不会内联),但这是微观优化。追求可读性+可维护性

内存影响可以忽略不计,但是通过在这么多方法中重复一个实现来违反规则对可维护性是不好的:是的,最好按照您的建议来做。

将重复的代码块折叠成通用函数显然是一个好方法。你有什么理由不这样做吗?如果你不信任传入的字符串,你可以使用枚举,但对于你的问题,它很好,因为你有很多重复的代码,所以把它折叠成通用的,然后使用访问器方法,这将有助于维护persepctive。代码的大小可能会更小,但并不重要……正如其他人所指出的,请确保新方法是私有的,并且调用它的每个属性的方法仍然是公共的。我想这是不言而喻的,但可能值得注意。