C# - 范围混乱

时间:2012-08-07 13:04:03

标签: c# scope

在我的代码中我有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移动到代码底部的Linq部分到它自己的部分。但要做到这一点,我必须拥有整个RealDriveInfo部分..

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

非常感谢任何反馈,谢谢。

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

我想要第三种方法 WriteInToDB(); = DB编写代码将从RealDriveInfo方法中获取并转移到此处。

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

希望这会增加一点意义:)

4 个答案:

答案 0 :(得分:2)

创建方法:

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 over here描述。

答案 1 :(得分:1)

我希望我能正确捕获您的功能。 3个地区,创造,输出,坚持。您可以在每个部分中创建可重用的方法。您可以将输出部分移至ToString()的{​​{1}}方法。

Server

答案 2 :(得分:1)

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

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

n.b。我已经“回答”了这个问题,因为它删除了重复,但可以说它不太可读。

    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);
    }

答案 3 :(得分:0)

在痛苦地意识到之后,答案就是方法和阶级范围......

只是想让任何人想看看我做了什么::

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();
    }

只需移动我希望被所有方法看到的部分,它就可以进入Class范围了。

感谢您的反馈:)