简体   繁体   English

C#中的通用值对象

[英]Generic Value Object in C#

I have a VO class that contains several variables incl. 我有一个VO类,其中包含几个变量。 a variable that can be of different types and to prevent casting later on I wonder if I can make that class generic. 一个可以具有不同类型的变量,以防止以后进行转换,我想知道是否可以使该类通用。

public class InputVO<T>
{
    public bool isEnabled;
    public T value;
}

Then I want to create an array of InputVOs and a method to get a typed InputVO... 然后,我想创建一个InputVO数组和一个获取类型化InputVO的方法。

public InputVO[] Inputs { get; private set; }

public InputVO GetInput(InputType type)
{
    return Inputs[(int)type];
}

How do I go about defining the array and the GetInput method so that they work with the generic InputVO? 我如何定义数组和GetInput方法,以便它们与通用InputVO一起使用? (The InputType type argument is an enum. Shouldn't really matter here, I think). InputType type参数是一个枚举。我认为在这里应该没关系)。

Generic type parameters are fixed at compile-time. 泛型类型参数在编译时是固定的。
Whenever you use InputVO, that type parameter needs to be filled in. 每当使用InputVO时,都需要填写该类型参数。

  public InputVO<T1>[] Inputs { get; private set; }

But what you seem to want is different InputVO objects for each datatype, and to be able to retrieve them by type at runtime: 但是您似乎想要的是每种数据类型都有不同的InputVO对象,并且能够在运行时按类型检索它们:

// Base class for all InputVOs
public abstract InputVOBase
{
    public bool isEnabled;
}

// InputVO for a specific data-type
public class InputVO<T> : InputVOBase
{
    public T Value;
}

Now you can use a dictionary from Type to InputVOBase. 现在,您可以使用从Type到InputVOBase的字典。

  // One InputVO per datatype
  public Dictionary<Type, InputVOBase> AllInputs { get; private set; }

  // Return the VO for type T, or null
  public InputVO<T> GetInput<T>()
  {
      InputVOBase vo = AllInputs[typeof(T)];

      return (vo as InputVO<T>);
  }

You cannot create an array of a generic class without specifying the type. 如果不指定类型,则无法创建通用类的数组。 However, as you have control over the base type, you can make that implement a non generic interface and have a collection of that instead: 但是,由于您可以控制基本类型,因此可以使它实现一个非通用接口,并具有该接口的集合:

//Empty interface 
public interface IInputVO { }

//Your generic class now implements the interface
public class InputVO<T> : IInputVO
{
    public bool isEnabled { get; set; }
    public T Value { get; set; }
}

So now your array is of the interface type IInputVO : 所以现在您的数组的接口类型为IInputVO

IInputVO[] inputs = 
{ 
    new InputVO<int>(),
    new InputVO<string>(),
    new InputVO<SomeClass>(),
};

Cleaned up solution a bit. 稍微清理一下解决方案。 Mainly you need to collect your values in a dictionary. 主要是您需要在字典中收集值。

void Main()
{
    var a = new InputVO<string> { Value = "test" };
    var b = new InputVO<int> { Value = 5 };
    Inputs.Add(typeof(string), a);
    Inputs.Add(typeof(int), b);

    var x = GetInput<string>();
    Console.WriteLine(x.Value);
    var y = GetInput<int>();
    Console.WriteLine(y.Value);
}

public abstract class InputVOBase
{
    public bool isEnabled;
}

public class InputVO<T> : InputVOBase
{
    public T Value;
}

public Dictionary<Type, InputVOBase> Inputs = new Dictionary<Type, InputVOBase>();

public InputVO<T> GetInput<T>()
{
    return Inputs[typeof(T)] as InputVO<T>;
}

Thanks for the tips anyone! 感谢任何人的提示! Phew, since there's no way getting around casting and I only need to regard a couple of types I think all the generics-based solutions are a bit overkill in my case. ew,因为没有办法解决强制转换问题,我只需要考虑几种类型,我认为所有基于泛型的解决方案在我看来都是过大的。 So I simply added casted getters to my VO ... 所以我只是在我的VO中添加了强制转换的吸气剂...

public class InputVO
{
    public bool isEnabled;
    public bool isValid;
    public InputType type;
    public object value;

    public int IntValue { get { return (int)value; } }
    public float FloatValue { get { return (float)value; } }
    public bool BoolValue { get { return (bool)value; } }
    public Vector2 Vector2Value { get { return (Vector2) value; } }
    public Vector3 Vector3Value { get { return (Vector3)value; } }
}

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

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