C# 创建依赖于字符串值的类型列表

C# 创建依赖于字符串值的类型列表,c#,generics,C#,Generics,假设我有一个.txt文件,其中: 第一个单词是类(甚至是用户定义的类)的类型或名称。所以它可以是编译器接受的任何东西 以下文字是该类型的值 例如: int 1 2 3 5 6 8 19 20 如何创建c#中第一个单词类型的列表?这类东西显然是非法的,但我还是要写出来,以明确我需要什么: static void Main(string[] args) { System.IO.StreamReader file = new Syst

假设我有一个.txt文件,其中:

  • 第一个单词是类(甚至是用户定义的类)的类型或名称。所以它可以是编译器接受的任何东西
  • 以下文字是该类型的值
  • 例如:

    int 1 2 3 5 6 8 19 20
    
    如何创建c#中第一个单词类型的列表?这类东西显然是非法的,但我还是要写出来,以明确我需要什么:

    static void Main(string[] args)
            {
                System.IO.StreamReader file = 
                new System.IO.StreamReader(@"c:\test.txt");
                string[] words = reader.ReadToEnd().Split(' ');
                List<words[0]> list = new List<words[0]>;
            }
    
    static void Main(字符串[]args)
    {
    System.IO.StreamReader文件=
    新System.IO.StreamReader(@“c:\test.txt”);
    string[]words=reader.ReadToEnd().Split(“”);
    列表=新列表;
    }
    
    即使这是可能的,操作
    list.add(word[i])
    也应该是一个问题(因为每个元素也是一个字符串)


    重要提示:项目细节中不允许反射,因为性能很差

    在C#中,如果不涉及某种方式的运行时反射,就无法做到这一点

    也许最实用的方法是使用
    dynamic

    var t = typeof(int); // or some other type based on the input
    dynamic list = Activator.CreateInstance(typeof(List<>).MakeGenericType(t));
    
    var t=typeof(int);//或基于输入的其他类型
    动态列表=Activator.CreateInstance(typeof(list).MakeGenericType(t));
    
    然后,您可以简单地使用
    list.Add(x)
    ,其中
    x
    是一个适当类型的值——但您也必须以某种方式将输入转换为该类型——您不能只添加从文件中读取的字符串

    后者可能比创建和使用列表本身更难解决:如何将字符串(通常从文件中读取)转换为用户指定的任意类型的值?

    我强烈建议不要尝试这样做,至少有你说的完全不受约束的要求

    至少有几个小问题是可以解决的:

  • 尽管你希望避免反思,但反思是必需的。要将包含类型名的简单字符串转换为您正在寻找的数据结构而不进行反射,根本没有实际的方法。通过使用“记忆化”模式(即缓存每种类型的反序列化对象,以避免每行输入的反射开销),以及使用
    Expression
    s构建缓存的反序列化对象,可以最大限度地减少性能问题(这将确保在实际处理数据时尽可能获得最佳性能)
  • 没有通用的方法来解析字符串值以创建某个任意类型的实例。您可以通过检查类型本身以查找可用于完成任务的方法来部分解决此问题。例如,使用反射查找名为“parse”的方法,并使用该方法将字符串转换为类型实例。但显然,这对缺少此类方法的类型不起作用;这不可调和地阻碍了真正处理任何可能类型的可能性
  • 还有一些更重要的问题(即极难或不可能解决):

  • 您的示例甚至不起作用,因为
    int
    不是实际的.NET类型名称。您必须使用特殊情况的C类型别名,如
    int
    bool
    long
    ,等等,才能使其起作用
  • 即使使用反射(这是正确的方法),您仍然需要完全限定的类型名来可靠地处理此问题。例如,对于正在执行的
    AppDomain
    来说,完全有可能将多个类型命名为
    Point
    。没有名称空间,就无法有效地解决歧义
  • 给定一个完全限定的类型名,.NET默认情况下将仅搜索正在执行的程序集和mscorlib.dll以查找给定的类型。如果要在其他程序集中查找类型,则必须自己进行搜索。显然,您最多只能处理由
    AppDomain
    的输入poi引用的程序集中包含的类型nt程序集。若要处理间接引用的程序集,您需要递归搜索程序集类型以查找您要查找的类型名称。显然,无法处理未知程序集中的类型
  • 从您的问题中根本不清楚您希望如何使用这些对象的泛型列表。使用泛型是很好的,例如,为了确保类型安全。但是,如果您不能为某个特定类型声明一个实际上属于
    列表
    类型的变量,那么对某些特定类型使用
    列表
    通常是非常不方便的e读取的特定类型
  • 可能最大的问题之一不是所有的类型都可以被表示为空间分隔的值!例如,如果输入的类型名称是“代码> Stry.String ”,请考虑输入文本的样子。如果任何字符串值本身都有一个空格,那么它将被错误地定义为值分隔符,当数据为PARS时会损坏数据。埃德 上面的一些问题可以通过约束问题来解决方法,要求流程中的一个程序集引用每个类型,限制该类型的可能值,或提供用于在文本中分隔或以其他方式格式化值的附加规则,等等。但只有在您愿意放弃您在任务中规定的原始广泛规范的情况下,这些方法才起作用激动

    理想情况下,您只需提前知道可能需要解析哪些类型,然后为每种类型编写特定的代码。这是最可靠的,尽管更耗时

    此主题的一个变体可能适用于您的场景,即使用(或类似的技术)提供外接程序机制,其中