Реализация интерфейса - C# (179705)
Формулировка задачи:
Написал пример из книги O'Reilly Learning C# 3.0 Chapter 18 создание File-Copier. Все сделал "по инструкции" и несколько раз перепроверил код, но работает с ошибками (их очень много), но хотел бы разобраться хотя бы по основным вопросам, указанных в комментариях (или подскажите где можно почитать):
1. fileList.Sort(comparer);//Почему мы здесь передаем ссылку на объект, в котором реализована только одна ф-ия
Compaprer, а не на саму функцию - comparer.Comparer(file1, file2)? Она же не должна вызываться сама по себе.. Как это возможно? (153 строка)
2. public int Comparer(FileInfo file1, FileInfo file2)// почему компилятор не видит здесь реализацию интерфейса?
//пробовал изменить название на IComparer<FileInfo>.Comparer, но безуспешно... Почему? (173)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; namespace File_Copier { public partial class FrmFileCopier : Form { private const int MaxLevel = 2; public FrmFileCopier() { InitializeComponent(); FillDirectoryTree(tvwSource, true); FillDirectoryTree(tvwTargetDir, false); } private void FillDirectoryTree(TreeView tvw, bool isSource) { tvw.Nodes.Clear(); string[] strDrives = Environment.GetLogicalDrives(); foreach(string rootDirectoryName in strDrives) { try { DirectoryInfo dir = new DirectoryInfo(rootDirectoryName); dir.GetDirectories(); TreeNode ndRoot = new TreeNode(rootDirectoryName);//create ndRoot to hold the directories tvw.Nodes.Add(ndRoot); if (isSource) { GetSubDirectoryNodes(ndRoot, ndRoot.Text, true, 1); } else { GetSubDirectoryNodes(ndRoot, ndRoot.Text, false, 1); } } catch { } Application.DoEvents(); } } private void GetSubDirectoryNodes(TreeNode parentNode, string fullName, bool getFileNames, int level) { DirectoryInfo dir = new DirectoryInfo(fullName); DirectoryInfo[] dirSubs = dir.GetDirectories(); foreach(DirectoryInfo dirSub in dirSubs) { if ((dirSub.Attributes & FileAttributes.Hidden) != 0) { continue; } TreeNode subNode = new TreeNode(dirSub.Name); parentNode.Nodes.Add(subNode); if (level < MaxLevel) { GetSubDirectoryNodes(subNode, dirSub.FullName, getFileNames, level + 1); } if (getFileNames) { FileInfo[] files = dir.GetFiles(); foreach(FileInfo file in files) { TreeNode fileNode = new TreeNode(file.Name); parentNode.Nodes.Add(fileNode); } } } } private void label1_Click(object sender, EventArgs e) { } private void tvwSource_AfterCheck(object sender, TreeViewEventArgs e) { SetCheck(e.Node, e.Node.Checked); } private void SetCheck(TreeNode node, bool check) { foreach(TreeNode n in node.Nodes) { n.Checked = check; //check the node if (n.Nodes.Count != 0) { SetCheck(n, check); } } } private void tvwSource_BeforeExpand(object sender, TreeViewCancelEventArgs e) { tvwExpand(sender, e.Node); } private void tvwExpand(object sender, TreeNode currentNode) { TreeView tvw = (TreeView)sender; bool getFiles = (tvw == tvwSource); string fullName = currentNode.FullPath; currentNode.Nodes.Clear(); GetSubDirectoryNodes(currentNode, fullName, getFiles, 1); } private void tvwTargetDir_BeforeExpand(object sender, TreeViewCancelEventArgs e) { tvwExpand(sender, e.Node); } private void tvwTargetDir_AfterSelect(object sender, TreeViewEventArgs e) { string theFullPath = e.Node.FullPath; if (theFullPath.EndsWith("")) { theFullPath = theFullPath.Substring(0, theFullPath.Length - 1); } txtTargetDir.Text = theFullPath; } private void btnClear_Click(object sender, EventArgs e) { foreach(TreeNode node in tvwSource.Nodes) { SetCheck(node, false); } } private void btnCopy_Click(object sender, EventArgs e) { List<FileInfo> fileList = GetFileList(); foreach(FileInfo file in fileList) { try { lblStatus.Text = "Copying " + txtTargetDir.Text + "" + file.Name + "..."; Application.DoEvents(); file.CopyTo(txtTargetDir.Text + "" + file.Name, chkOverwrite.Checked); } catch(Exception ex) { MessageBox.Show(ex.Message); } } lblStatus.Text = "Done."; //Application.DoEvents(); } private List<FileInfo> GetFileList() { List<string> fileNames = new List<string>(); foreach(TreeNode theNode in tvwSource.Nodes) { GetCheckedFiles(theNode, fileNames); } List<FileInfo> fileList = new List<FileInfo>(); foreach(string fileName in fileNames) { FileInfo file = new FileInfo(fileName); if (file.Exists) { fileList.Add(file); } } IComparer<FileInfo> comparer = (IComparer<FileInfo>) new FileComparer();// создаем интерфейсную ссылку на объект класса fileList.Sort(comparer);//Почему мы здесь передаем ссылку на объект, в котором реализована только одна ф-ия //Compaprer, а не на саму функцию? Она же не вызывается сама по себе... return fileList; } private void GetCheckedFiles(TreeNode node, List<string> fileNames) { if(node.Nodes.Count==0)//if this is a leaf... { if(node.Checked)//if the node was checked... { fileNames.Add(node.FullPath);//if the node was checked... } } else { foreach(TreeNode n in node.Nodes) { GetCheckedFiles(n, fileNames); } } } public class FileComparer: IComparer<FileInfo> { public int Comparer(FileInfo file1, FileInfo file2)// почему компилятор не видит здесь реализацию интерфейса? //пробовал изменить название на IComparer<FileInfo>.Comparer, но безуспешно... Почему? { if (file1.Length > file2.Length) { return -1; } if (file1.Length < file2.Length) { return 1; } return 0; } int IComparer<FileInfo>.Compare(FileInfo x, FileInfo y)// этой функции в примере нет, но без нее не работает - // не реализован интерфейс { throw new NotImplementedException(); } } private void btnDelete_Click(object sender, EventArgs e) { System.Windows.Forms.DialogResult result = MessageBox.Show( "Are you quite sure?", "Delete Files", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2); if(result== System.Windows.Forms.DialogResult.OK) { List<FileInfo> fileNames = GetFileList(); foreach (FileInfo file in fileNames) { try { lblStatus.Text = "Deleting " + txtTargetDir.Text + "" + file.Name + "..."; Application.DoEvents(); file.Delete(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } lblStatus.Text = "Done."; Application.DoEvents(); } } private void btnCancel_Click(object sender, EventArgs e) { Application.Exit(); } } }
Решение задачи: «Реализация интерфейса»
textual
Листинг программы
void Sort(IComparer comparer) { ... int result = comparer.Compare(arr[i], arr[j]); ... }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д