Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中创建一个可以处理多个返回类型的函数#_C#_C# 3.0 - Fatal编程技术网

C# 在C中创建一个可以处理多个返回类型的函数#

C# 在C中创建一个可以处理多个返回类型的函数#,c#,c#-3.0,C#,C# 3.0,我对C#比较陌生,以前大部分编程都是用VB6完成的。我知道C#的类型比VB明确得多,但我希望我的问题有一个解决方案 我正在从事一个项目,该项目旨在打开、解析、验证并最终编辑5个不同的CSV文件,这些文件用作我们使用的应用程序的输入。手动操作CSV文件是现在要做的事情,但由于缺乏原始开发人员的文档和支持,对大多数用户来说很困难。我的目标是构建一个GUI,允许用户直接编辑字段并创建一个新的CSV文件以用作导入。以下是现在的基本结构: public class Dataset { public

我对C#比较陌生,以前大部分编程都是用VB6完成的。我知道C#的类型比VB明确得多,但我希望我的问题有一个解决方案

我正在从事一个项目,该项目旨在打开、解析、验证并最终编辑5个不同的CSV文件,这些文件用作我们使用的应用程序的输入。手动操作CSV文件是现在要做的事情,但由于缺乏原始开发人员的文档和支持,对大多数用户来说很困难。我的目标是构建一个GUI,允许用户直接编辑字段并创建一个新的CSV文件以用作导入。以下是现在的基本结构:

public class Dataset
{
    public Dictionary<string,File1> file1 = new Dictionary<string,File1>();
    public Dictionary<string,File2> file2 = new Dictionary<string,File2>();
    public Dictionary<string,File3> file3 = new Dictionary<string,File3>();
    public Dictionary<string,File4> file4 = new Dictionary<string,File4>();
    public Dictionary<string,File5> file5 = new Dictionary<string,File5>();

    public void SelectFiles()
    {
        //User specifies which file(s) are to be opened (default is all 5 files)
    }

    public class File1
    {
        public string Field_1 {get ; set}
        public string Field_2 {get ; set}
        .
        .
        .
        public string Field_10 {get ; set}
    }
    public class File2
    {
        public string Field_1 {get ; set}
        public string Field_2 {get ; set}
        .
        .
        .
        public string Field_31 {get ; set}
    }
    public class File3
    {
        public string Field_1 {get ; set}
        public string Field_2 {get ; set}
        .
        .
        .
        public string Field_57 {get ; set}
    }
    public class File4
    {
        public string Field_1 {get ; set}
        public string Field_2 {get ; set}
        .
        .
        .
        public string Field_68 {get ; set}
    }
    public class File5
    {
        public string Field_1 {get ; set}
        public string Field_2 {get ; set}
        .
        .
        .
        public string Field_161 {get ; set}
    }
}
公共类数据集
{
公共字典文件1=新字典();
公共字典文件2=新字典();
公共字典文件3=新字典();
公共字典文件4=新字典();
公共字典文件5=新字典();
public void SelectFiles()
{
//用户指定要打开的文件(默认为所有5个文件)
}
公共类文件1
{
公共字符串字段_1{get;set}
公共字符串字段_2{get;set}
.
.
.
公共字符串字段_10{get;set}
}
公共类文件2
{
公共字符串字段_1{get;set}
公共字符串字段_2{get;set}
.
.
.
公共字符串字段_31{get;set}
}
公共类文件3
{
公共字符串字段_1{get;set}
公共字符串字段_2{get;set}
.
.
.
公共字符串字段_57{get;set}
}
公共类文件4
{
公共字符串字段_1{get;set}
公共字符串字段_2{get;set}
.
.
.
公共字符串字段_68{get;set}
}
公共类文件5
{
公共字符串字段_1{get;set}
公共字符串字段_2{get;set}
.
.
.
公共字符串字段_161{get;set}
}
}
挑战在于将CSV中的数据读入每个词典。现在这是用5个不同的函数完成的(实际上一个函数重载了5次)

公共字典readfile(字符串文件)
{
//打开并解析文件#1,并存储在File1类中,由File1字典访问
}
公共字典ReadFile(字符串文件)
{
//打开并解析文件#2,并存储在File2类中,由File2字典访问
}
公共字典ReadFile(字符串文件)
{
//打开并解析文件#3,并存储在File3类中,由File3字典访问
}
公共字典ReadFile(字符串文件)
{
//打开并解析文件#4,并存储在File4类中,由File4字典访问
}
公共字典ReadFile(字符串文件)
{
//打开并解析文件#5,并存储在File5类中,由File5字典访问
}
打开和解析CSV文件的代码实际上完全相同,只是字典的类型不同。因此,当我对这个函数进行更改时,我必须确保对其他4个函数进行了相同的更改,我担心这会使将来维护代码变得更加困难。是否有任何可能的方法可以创建一个没有重载的函数,在这里我可以将类型作为参数传递给函数

public Dictionary<string,[UnknownType]>ReadFile(string file, [UnknownType] typ)
{
    //Open and Parse File and read into class specified by typ
}
publicDictionaryReadFile(字符串文件,[UnknownType]类型)
{
//打开并解析文件并读入由typ指定的类
}

必须使
文件
类继承基类并返回它:

public abstract classFileBase
{
    // include common features here
}

public class File1 : FileBase
{
    public string Field_1 {get ; set}
    public string Field_2 {get ; set}
    .
    .
    .
    public string Field_10 {get ; set}
}

public Dictionary<string, FileBase>ReadFile(string file)
{
    //Open and Parse File and read into class specified by typ
}
公共抽象类文件库
{
//在此处包括常见功能
}
公共类File1:FileBase
{
公共字符串字段_1{get;set}
公共字符串字段_2{get;set}
.
.
.
公共字符串字段_10{get;set}
}
公共字典ReadFile(字符串文件)
{
//打开并解析文件并读入由typ指定的类
}
为什么不为“未知”类型使用object(所有.NET类型的基础)?然后,您可以根据需要对其进行测试/强制转换


但是,函数重载有什么问题吗?似乎非常适合这种情况。不要忘记,您可以有5个公共重载函数,然后这些函数可以委托给私有函数,以任何方式实现您的目标。

面向对象,我的朋友。从VB6的角度来看,这可能不是您所习惯的。但是,与其使用File1->File5,不如使用一个“CVSFile”--对象,如果您确实需要的话,可以从中派生出来。这会在很多方面帮助你

多态性

查看MSDN,了解如何使用

MSDN中的代码片段:

public class BaseClass
{
    public void DoWork() { }
    public int WorkField;
    public int WorkProperty
    {
        get { return 0; }
    }
}

public class DerivedClass : BaseClass
{
    public new void DoWork() { }
    public new int WorkField;
    public new int WorkProperty
    {
        get { return 0; }
    }
}

DerivedClass B = new DerivedClass();
B.DoWork();  // Calls the new method.

BaseClass A = (BaseClass)B;
A.DoWork();  // Calls the old method.
编辑

只是想澄清一下

当使用new关键字时,new 调用类成员而不是 已删除的基类成员 替换。那些基类成员是 称为隐藏成员。隐藏类 如果出现以下情况,仍然可以调用成员: 派生类的实例被强制转换 到基类的实例

如果您想改用虚拟方法:

为了获得一个派生的 类完全接管一个类 来自基类的成员,基类 类必须将该成员声明为 事实上的这是通过 将virtual关键字添加到 成员的返回类型。派生的 类则可以选择使用 覆盖关键字,而不是新关键字,以 替换基类实现 用它自己的

在这种情况下,结果将是这样

DerivedClass B = new DerivedClass();
B.DoWork();  // Calls the new method.

BaseClass A = (BaseClass)B;
A.DoWork();  // Also calls the new method.
所有示例均取自MSDN

如何将此应用于您的示例

假设您有一个LoadCSV方法,而不是有5个不同的方法返回每个对象,您可以很容易地说“嘿,我将返回一个CVSFile,您不关心其他任何事情!”

那里有很多不错的电视剧,还有“儿童节目”
public class BaseClass
{
    public virtual void DoWork() { }
    public virtual int WorkProperty
    {
        get { return 0; }
    }
}
public class DerivedClass : BaseClass
{
    public override void DoWork() { }
    public override int WorkProperty
    {
        get { return 0; }
    }
}
DerivedClass B = new DerivedClass();
B.DoWork();  // Calls the new method.

BaseClass A = (BaseClass)B;
A.DoWork();  // Also calls the new method.
public abstract class FileBase
{
    public virtual void DoSomeParsing()
    {
    }
}

public class File1 : FileBase
{
}

public class Test
{
    public Dictionary<string, T> ReadFile<T>(string file) where T : FileBase, new()
    {
        Dictionary<string, T> myDictionary = new Dictionary<string, T>();
        myDictionary.Add(file, new T());
        myDictionary[file].DoSomeParsing();
        return myDictionary;
    }

    public object Testit()
    {
        Test test = new Test();
        return test.ReadFile<File1>("C:\file.txt");
    }
}
Dictionary<string, T> ReadFile<T>(string f) {...}
...
Dictionary<string, File1> d = ReadFile<File1>(filename);
class Base {
  virtual ReadFile();
}

class File1: Base {
    override ReadFile(); //Reads File1
}


class File2: Base {
    override ReadFile(); //Reads File2
}
List<Base> baseList
if(I need to read file File1)
   baseList.Add(new File1());
public interface IParser
{
    object Parse(string input);
}
public interface IParser<T> : IParser
{
    new T Parse(string input);
}
public class MyParser : IParser<MyObject>
{
    #region IParser<MyObject> Members

    public MyObject Parse(string input)
    {
        if (string.IsNullOrEmpty(input))
            throw new ArgumentNullException("input");
        if (input.Length < 3)
            throw new ArgumentOutOfRangeException("input too short");

        return new MyObject()
        {
            Field1 = input.Substring(0, 1),
            Field2 = input.Substring(1, 1),
            Field3 = input.Substring(2, 1)
        };
    }

    object IParser.Parse(string input)
    {
        return this.Parse(input);
    }

    #endregion
}
public class MyObject
{
    public string Field1 { get; set; }
    public string Field2 { get; set; }
    public string Field3 { get; set; }
}
public static class ToolKit
{
    public static Dictionary<string, TResult> ReadFile<TParser, TResult>(
            this string fileName)
        where TParser : IParser<TResult>, new()
        where TResult : class
    {
        return fileName.AsLines()
                       .ReadFile<TParser, TResult>();
    }

    public static Dictionary<string, TResult> ReadFile<TParser, TResult>(
            this IEnumerable<string> input)
        where TParser : IParser<TResult>, new()
        where TResult : class
    {
        var parser = new TParser();

        var ret = input.ToDictionary(
                        line => line, //key
                        line => parser.Parse(line)); //value
        return ret;
    }

    public static IEnumerable<string> AsLines(this string fileName)
    {
        using (var reader = new StreamReader(fileName))
            while (!reader.EndOfStream)
                yield return reader.ReadLine();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var result = new[] { "123", "456", "789" }
            .ReadFile<MyParser, MyObject>();

        var otherResult = "filename.txt".ReadFile<MyParser, MyObject>();
    }
}
List<List<string>> Parse(string file)
{
  List<List<string>> result = new List<List<string>>();
  using (TextReader reader = File.OpenText(file))
  {
    string line = reader.ReadLine();
    while (line != null)
    {
      result.Add(new List<string>(line.Split(',')));
      line = reader.ReadLine();
    }
  }
  return result;
}
Dictionary<int, File1> file1 = Parse("file1.csv");
Console.Write(file1[0].Field_5);
List<List<string>> file1 = Parse("file1.csv");
Console.Write(file1[0][5]);
List<List<string>> file1 = Parse("file1.csv");
Console.Write(file1[0]["SomeFieldName"]);