简体   繁体   English

一类中的泛型和定义类型

[英]Generic and defined types in one class

Is it possible to have generic types and non-generic types in one class?? 一类中是否可以有泛型和非泛型?

I have a class in which I have to manage different types but I don't know exactly what I'm going to receive, I though about using generics but I have not found a way for doing this. 我有一个必须管理不同类型的类,但是我不知道我将要收到什么,尽管我使用泛型,但是我还没有找到一种方法来实现。

This is what I am trying to do 这就是我想要做的

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

I have to read 4 string lines out of a text file, and try to parse those lines into 我必须从文本文件中读取4个字符串行,然后尝试将这些行解析为

  1. int INT
  2. float 浮动
  3. boolean 布尔
  4. leave it as a string 保留为字符串

(First trying to parse it to 1, if not possible to 2, if not possible to 3, if not possible to 4.) (首先尝试将其解析为1,如果无法解析为2,如果无法解析为3,如果无法解析为4。)

And after knowing what type is each argument, define each variable with the its respective type 在知道每个参数是什么类型之后,用各自的类型定义每个变量

For instance with a text file with 例如带有一个文本文件

  • commandCode=2 commandCode = 2
  • arg1=true arg1 = true
  • arg2=256 arg2 = 256
  • arg3=dont arg3 = dont

I would have an object with 我会有一个对象

  • int commandCode int commandCode
  • < bool > arg1 <bool> arg1
  • < int > arg2 <int> arg2
  • < string> arg3 <字符串> arg3

And that would happen for any combination possible for arg1 to arg3. 对于arg1到arg3的任何组合,都会发生这种情况。

If I understnad you correctly you can only determine the actual type at runtime. 如果我理解正确,则只能在运行时确定实际类型。 In that csae generics won't help you much since any type argument needs to be resolved at compile time therefor you need to use reflection in some manner. 在那种情况下,csae泛型将无济于事,因为任何类型参数都需要在编译时进行解析,因此您需要以某种方式使用反射。 Below is a factory that could be extended to support your needs. 以下是可以扩展以支持您的需求的工厂。 You might or might not need 16 different methods depending on how many subclasses you have in reality (you'd need one for each subclass with the below approach) you could also skip the Create method and select the appropriate class/constructor directly 您可能需要或可能不需要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){
            ....
       }
   }
}

If you have variable types depending on the data you read (like in your case) it doesn't make much sense to use generics. 如果根据读取的数据具有变量类型(例如您的情况),则使用泛型没有多大意义。 Even if you take @Spontifixus approach you are not able to put all the created elements in one List<T> , cause due to the different types used in each object you need for each combination your own List<T> . 即使您采用@Spontifixus方法,也无法将所有创建的元素放在一个List<T> ,但由于每种对象使用的类型不同,因此每种组合都需要使用自己的List<T> Also if you later in code like to work with all the arguments, you need to query for each generic type to know how to read the desired value out of the current instance. 同样,如果您以后在代码中喜欢使用所有参数,则需要查询每种通用类型,以了解如何从当前实例中读取所需的值。

If you still think you need generic types (in this case) you can help yourself by using a generic class a creator method and a normal interface: 如果仍然认为需要通用类型(在这种情况下),则可以使用通用类,创建者方法和常规接口来帮助自己:

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; }
    }
}

By using this approach you can create a instance through type inference by calling the creator method and put all of them in one list: 通过使用这种方法,您可以通过调用creator方法通过类型推断来创建实例,并将所有实例放在一个列表中:

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

Now you got your generic objects in one list, but how do you work with this list? 现在,您将通用对象放在一个列表中,但是如何使用此列表呢? At last you're going all the time using the ICommand interface and stick to the object , making the generics useless. 最后,您将始终使用ICommand接口并坚持使用该object ,从而使泛型无用。 But maybe you don't think so and this approach might help. 但是也许您不这么认为,这种方法可能会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM