C# - 范围混淆

本文关键字:范围 | 更新日期: 2024-10-25 20:09:37

在我的代码中,我有 3 个部分,但在 3 个部分中的 2 个部分中,代码几乎相同,我想知道是否有人可以帮助我正确构建它们,这样我只需要在范围内写一行,以便两个部分都可以看到它,所以我不需要那么多代码。(框架3.5)

public static void FakeDriveInfo()
{
    List<DriveInfo> driveList = DriveInfo.GetDrives().Where(x => x.IsReady).ToList<DriveInfo>();
    Server server = new Server();
    Console.WriteLine();
    Console.ForegroundColor = ConsoleColor.White;
    Console.WriteLine("Server ID :      {0}", server.ServerID = 0);
    Console.WriteLine("Server Name :    {0}", server.ServerName = string.Concat(System.Environment.MachineName));
    Console.WriteLine();
    for (int i = 0; i < driveList.Count; i++)
    {
        ServerDrive serverDrives = new ServerDrive();
        Console.WriteLine("Drive Letter:    {0}", driveList[i].Name);
        Console.WriteLine("Total Size:      {0}", FormatBytes(driveList[i].TotalSize));
        Console.WriteLine("Volume Label:    {0}", driveList[i].VolumeLabel);
        Console.WriteLine("Free Space:      {0}", FormatBytes(driveList[i].TotalFreeSpace));
        Console.WriteLine("Drive Format:    {0}", driveList[i].DriveFormat);
        Console.ReadLine();
    }
}
public static void RealDriveInfo()
{
    //Create the server object - You will need create a list of the server objects.
    Server server = new Server();
    //Get all drives information
    List<DriveInfo> driveList = DriveInfo.GetDrives().Where(x => x.IsReady).ToList<DriveInfo>();
    //Insert information of one server - You will need get information of all servers
    server.ServerID = 0; //Here is necessery put PK key. I recommend doing the SQL server will automatically generate the PK.
    server.ServerName = string.Concat(System.Environment.MachineName);
    //Inserts information in the newServers object
    for (int i = 0; i < driveList.Count; i++)
    {
        ServerDrive serverDrives = new ServerDrive();
        //Put here all the information to obeject Server                
        serverDrives.DriveLetter = driveList[i].Name;
        serverDrives.TotalSpace = driveList[i].TotalSize;
        serverDrives.DriveLabel = driveList[i].VolumeLabel;
        serverDrives.FreeSpace = driveList[i].TotalFreeSpace;
        serverDrives.DriveType = driveList[i].DriveFormat;
        //      server.ListServerDrives.Add(serverDrives);
        server.ServerDrives.Add(serverDrives);
    }
    //Add the information to an SQL Database using Linq.
    DataClasses1DataContext db = new DataClasses1DataContext(@"sqlserver");
    //   db.Servers.InsertAllOnSubmit(server);
    db.Servers.InsertOnSubmit(server);
    db.SubmitChanges();
}

我想做的是将代码底部的 SQL to Linq 部分移到它自己的部分。但要做到这一点,我还必须拥有整个RealDriveInfo部分。

我想做的另一部分是制作List<DriveInfo> driveList = DriveInfo.GetDrives().Where(x=>x.IsReady).ToList<DriveInfo>();,以便FakeDriveInfo和RealDriveInfo可以看到它。

任何反馈将不胜感激,谢谢。

编辑:目前我正在调用两个方法,FakeDriveInfo();= 执行控制台应用程序并向我显示它将提交的信息。名称、字母、标签、服务器名称、ID 等RealDriveInfo();= 连接到 SQL Server 并将信息插入到两个表中。

我想有第三种方法WriteInToDB();= 数据库编写代码将取自 RealDriveInfo 方法并移至此处。

目前,由于范围的原因,我有两种方法实际上看起来相同。我希望范围发生变化,以便我可以将代码的 List 部分放入 Main() 方法中,并且 FakeDriveInfo 和 RealDriveInfo 都可以从那里使用它,而不是复制代码。

希望这能为这一切增添更多意义:)

C# - 范围混淆

创建一个方法:

public static List<DriveInfo> GetDrives {
    return DriveInfo.GetDrives().Where(x => x.IsReady).ToList<DriveInfo>();
}

在两个地方都调用它:

public static void FakeDriveInfo()
{
    List<DriveInfo> driveList = GetDrives();
    // ...
}
public static void RealDriveInfo()
{
    List<DriveInfo> driveList = GetDrives();
    // ....
}

这是基本的重构之一。它被称为提取方法,马丁·福勒(Martin Fowler)在这里进行了描述。

我希望我正确捕获了您的功能。3 个区域,创建、输出、持久。当然,您可以获取每个部分并创建可重用的方法。您可以将输出部分移动到ServerToString()方法。

        #region create graph
        var server = new Server()
        {
            ServerID = 0,
            ServerName = string.Concat(Environment.MachineName),
            ServerDrives = DriveInfo.GetDrives()
                                    .Where(x => x.IsReady)
                                    .Select(di => new ServerDrive()
                                    {
                                        DriveLetter = di.Name,
                                        TotalSpace = di.TotalSize,
                                        DriveLabel = di.VolumeLabel,
                                        FreeSpace = di.TotalFreeSpace,
                                        DriveType = di.DriveFormat
                                    })
                                    .ToList()
        };
        #endregion
        #region output graph
        Console.WriteLine();
        Console.ForegroundColor = ConsoleColor.White;
        Console.WriteLine("Server ID :      {0}", server.ServerID);
        Console.WriteLine("Server Name :    {0}", server.ServerName);
        Console.WriteLine();
        server.ServerDrives.ForEach(sd =>
        {
            Console.WriteLine("Drive Letter:    {0}", sd.DriveLetter);
            Console.WriteLine("Total Size:      {0}", sd.TotalSpace);
            Console.WriteLine("Volume Label:    {0}", sd.DriveLabel);
            Console.WriteLine("Free Space:      {0}", sd.FreeSpace);
            Console.WriteLine("Drive Format:    {0}", sd.DriveType);
            Console.ReadLine();
        });
        #endregion
        #region persist graph
        DataClasses1DataContext db = new DataClasses1DataContext(@"sqlserver");
        db.Servers.InsertOnSubmit(server);
        db.SubmitChanges();
        #endregion

我采用了创建一个新方法的方法,ProcessDriveInfo,由您的两个原始方法调用。这两种方法获取驱动器列表,创建服务器,对服务器执行某些操作,并为每个驱动器执行某些操作。我将前两个步骤移到ProcessDriveInfo中,并传递了最后两个步骤的操作。

第一个操作(即方法)对服务器执行某些操作,第二个操作对单个driveInfo执行某些操作。

:注:我已经"回答"了这个问题,因为它删除了重复,但可以说它的可读性较差。

    public Server ProcessDriveInfo(Action<Server> initialAction, Action<Server, DriveInfo> driveInfoAction)
    {
        var driveList = DriveInfo.GetDrives().Where(x => x.IsReady).ToList();
        var server = new Server();
        initialAction(server);
        driveList.ForEach(dl => driveInfoAction(server, dl));
        return server;
    }
    public void FakeDriveInfo()
    {
        ProcessDriveInfo(WriteServerToConsole, WriteDriveInfoToConsole);
    }
    private void WriteServerToConsole(Server server)
    {
        Console.WriteLine();
        Console.ForegroundColor = ConsoleColor.White;
        Console.WriteLine("Server ID :      {0}", server.ServerID = 0);
        Console.WriteLine("Server Name :    {0}", server.ServerName = string.Concat(System.Environment.MachineName));
        Console.WriteLine();
    }
    private void WriteDriveInfoToConsole(Server server, DriveInfo t)
    {
        Console.WriteLine("Drive Letter:    {0}", t.Name);
        Console.WriteLine("Total Size:      {0}", FormatBytes(t.TotalSize));
        Console.WriteLine("Volume Label:    {0}", t.VolumeLabel);
        Console.WriteLine("Free Space:      {0}", FormatBytes(t.TotalFreeSpace));
        Console.WriteLine("Drive Format:    {0}", t.DriveFormat);
        Console.ReadLine();
    }
    public void RealDriveInfo()
    {
        var server = ProcessDriveInfo(InitialiseServer, WriteDriveInfoToServer);
        //Add the information to an SQL Database using Linq.
        var db = new DataClasses1DataContext(@"sqlserver");
        //   db.Servers.InsertAllOnSubmit(server);
        db.Servers.InsertOnSubmit(server);
        db.SubmitChanges();
    }
    private static void InitialiseServer(Server server)
    {
        // Insert information of one server - You will need get information of all servers
        server.ServerID = 0;
        // Here is necessery put PK key. I recommend doing the SQL server will automatically generate the PK.
        server.ServerName = Environment.MachineName;
    }
    private static void WriteDriveInfoToServer(Server server, DriveInfo t)
    {
        var serverDrives = new ServerDrive
                               {
                                   DriveLetter = t.Name,
                                   TotalSpace = t.TotalSize,
                                   DriveLabel = t.VolumeLabel,
                                   FreeSpace = t.TotalFreeSpace,
                                   DriveType = t.DriveFormat
                               };
        server.ServerDrives.Add(serverDrives);
    }

在痛苦地意识到之后,答案在方法和类范围内。

以防万一有人想看看我做了什么::

public class Program
{
    List<DriveInfo> driveList = DriveInfo.GetDrives().Where(x => x.IsReady).ToList<DriveInfo>(); //Get all the drive info
    Server server = new Server();  //Create  the server object
    ServerDrive serverDrives = new ServerDrive();
    public void Main()
    {
        Program c = new Program();
        c.FakeDriveInfo();
        c.RealDriveInfo();
        c.WriteInToDB();
    }
    public static string FormatBytes(long bytes)
    {
        const int scale = 1024;
        string[] orders = new string[] { "GB", "MB", "KB", "Bytes" };
        long max = (long)Math.Pow(scale, orders.Length - 1);
        foreach (string order in orders)
        {
            if (bytes > max)
            {
                return string.Format("{0:##.##} {1}", Decimal.Divide(bytes, max), order);
            }
            max /= scale;
        }
        return "0 Bytes";
    }
    public void FakeDriveInfo()
        {
            Console.WriteLine();
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("Server ID :      {0}", server.ServerID = 0);
            Console.WriteLine("Server Name :    {0}", server.ServerName = string.Concat(System.Environment.MachineName));
            Console.WriteLine();

            for (int i = 0; i < driveList.Count; i++)
            {
                Console.WriteLine("Drive Letter:    {0}", driveList[i].Name);
                Console.WriteLine("Total Size:      {0}", FormatBytes(driveList[i].TotalSize));
                Console.WriteLine("Volume Label:    {0}", driveList[i].VolumeLabel);
                Console.WriteLine("Free Space:      {0}", FormatBytes(driveList[i].TotalFreeSpace));
                Console.WriteLine("Drive Format:    {0}", driveList[i].DriveFormat);
                Console.ReadLine();
            }
        }
    public void RealDriveInfo()
         {

            //Insert information of one server - You will need get information of all servers
            server.ServerID = 0; //Here is necessery put PK key. I recommend doing the SQL server will automatically generate the PK.
            server.ServerName = string.Concat(System.Environment.MachineName);
            //Inserts information in the newServers object
            for (int i = 0; i < driveList.Count; i++)
            {
                //Put here all the information to obeject Server                
                serverDrives.DriveLetter = driveList[i].Name;
                serverDrives.TotalSpace = driveList[i].TotalSize;
                serverDrives.DriveLabel = driveList[i].VolumeLabel;
                serverDrives.FreeSpace = driveList[i].TotalFreeSpace;
                serverDrives.DriveType = driveList[i].DriveFormat;
                server.ServerDrives.Add(serverDrives);
            }
         }
    public void WriteInToDB()
    {
        //Add the information to an SQL Database using Linq.
        DataClasses1DataContext db = new DataClasses1DataContext(@"cspsqldev");
        //   db.Servers.InsertAllOnSubmit(server);
        db.Servers.InsertOnSubmit(server);
        db.SubmitChanges();
    }

只需将我希望通过所有方法看到的部分移动到类范围内,它现在就可以工作了。

感谢您的反馈,伙计们:)