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 都可以从那里使用它,而不是复制代码。
希望这能为这一切增添更多意义:)
创建一个方法:
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 个区域,创建、输出、持久。当然,您可以获取每个部分并创建可重用的方法。您可以将输出部分移动到Server
的ToString()
方法。
#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();
}
只需将我希望通过所有方法看到的部分移动到类范围内,它现在就可以工作了。
感谢您的反馈,伙计们:)