一个类中的泛型和定义类型

时间:2013-01-09 12:38:24

标签: c# class generics

是否可以在一个类中使用泛型类型和非泛型类型?

我有一个班级,我必须管理不同类型,但我不知道我将收到什么,我虽然使用泛型,但我没有找到办法做到这一点。

这就是我想要做的事情

int commandCode;
<T> arg1;
<T> arg2;
<T> arg3;

我必须从文本文件中读取4个字符串行,并尝试将这些行解析为

  1. INT
  2. 布尔
  3. 将其保留为字符串
  4. (首先尝试将其解析为1,如果不可能解析为2,如果不可能则为3,如果不可能则为4。)

    在知道每个参数的类型后,使用其各自的类型

    定义每个变量

    例如,带有

    的文本文件
    • commandCode = 2
    • ARG1 =真
    • ARG2 = 256
    • ARG3 =不要

    我会有一个

    的对象
    • int commandCode
    • &LT; bool&gt; ARG1
    • &LT; int&gt; ARG2
    • &LT;串GT; ARG3

    对于arg1到arg3的任何组合都会发生这种情况。

2 个答案:

答案 0 :(得分:1)

如果我正确地知道你,你只能在运行时确定实际类型。因为csae泛型对你没什么帮助,因为任何类型的参数都需要在编译时解决,你需要以某种方式使用反射。以下是可以扩展以满足您需求的工厂。您可能需要或可能不需要16种不同的方法,具体取决于您实际拥有多少个子类(您需要使用以下方法为每个子类创建一个子类),您也可以跳过Create方法并直接选择适当的类/构造函数

public class Command {

   public static Command Create(string[] textLines) {
     var args = textLines.Select(l => parseLine(l));
     var argTypes = args.Select(a => a.GetType().ToArray();
     return (Command)typeof(Command).GetMethod("Create",argTypes).Invoke(null,args);
   }

   public static Command Create(int commandType,
                                bool IsSponk,
                                int count, 
                                string description){
       return new CommandType1(commandType,
                               IsSponk,
                               count,
                               description);
   }
   private class CommandType1 : Command {
       public CommandType1(int commandType, bool IsSponk, int count, string description){
            ....
       }
   }
}

答案 1 :(得分:0)

如果根据您阅读的数据(例如您的情况)有可变类型,则使用泛型没有多大意义。即使您采用@Spontifixus方法,也无法将所有创建的元素放在一个List<T>中,因为每个组合中使用的每个对象使用的类型不同,因此List<T>。此外,如果您稍后在代码中使用所有参数,则需要查询每个泛型类型以了解如何从当前实例中读取所需的值。

如果你仍然认为你需要泛型类型(在这种情况下),你可以通过使用泛型类创建者方法和普通接口来帮助自己:

public interface ICommand
{
    int CommandCode { get; set; }
    object Argument1 { get; }
    object Argument2 { get; }
    object Argument3 { get; }
}

public static class Command
{
    public static Command<T1, T2, T3> Create<T1, T2, T3>(int code, T1 arg1, T2 arg2, T3 arg3)
    {
        return new Command<T1, T2, T3>(code, arg1, arg2, arg3);
    }
}

public class Command<T1, T2, T3> : ICommand
{
    public Command(int code, T1 arg1, T2 arg2, T3 arg3)
    {
        CommandCode = code;
        Argument1 = arg1;
        Argument2 = arg2;
        Argument3 = arg3;
    }

    public int CommandCode { get; set; }
    public T1 Argument1 { get; set; }
    public T2 Argument2 { get; set; }
    public T3 Argument3 { get; set; }

    object ICommand.Argument1
    {
        get { return Argument1; }
    }

    object ICommand.Argument2
    {
        get { return Argument2; }
    }

    object ICommand.Argument3
    {
        get { return Argument3; }
    }
}

通过使用这种方法,您可以通过调用creator方法通过类型推断创建实例,并将所有这些方法放在一个列表中:

var commands = new List<ICommand>();
var myCommand = Command.Create(3, 4f, true, "hello world");
var commands.Add(myCommand);

现在您将通用对象放在一个列表中,但是如何使用此列表?最后你会一直使用ICommand界面并坚持object,这使得泛型毫无用处。但也许你不这么认为,这种做法可能有所帮助。