开发者

Replacing non type safe with type safe generic method

开发者 https://www.devze.com 2023-04-01 08:24 出处:网络
Im looking for a way to replace the following: public class NonTypeSafe { private List<object> contents = new List<object>();

Im looking for a way to replace the following:

public class NonTypeSafe
{
    private List<object> contents = new List<object>();
    public List<object> Contents {get { return contents; }};

    public NonTypeSafe(params object[] arguments)
    {
        foreach(object arg in arguments)
        {
            contents.Add(arg);
        }
    }
}

with something that is typesafe. The aim is to have an object into which i can add numerous objects of varying types. At present, checks have to be made when retrieving the objects to determine whether or not they are of the correct type / in the correct order.

At present i have the following:

public class TypeSafe<T1>
  {
    protected List<object> ArgList = new List<object>();

    private readonly T1 arg1;

    public TypeSafe(T1 arg1)
    {
      ArgList.Add(arg1);
      this.arg1 = arg1;
    }

    public T1 Arg1
    {
      get { return (T1) ArgList[ArgList.IndexOf(arg1)]; }
    }
  }



  public class TypeSafe<T1, T2> : TypeSafe<T1>
  {

    private readonly T2 arg2;

    public TypeSafe(T1 arg1, T2 a开发者_运维百科rg2) : base(arg1)
    {
      ArgList.Add(arg2);
      this.arg2 = arg2;
    }

    public T2 Arg2
    {
      get { return (T2) ArgList[ArgList.IndexOf(arg2)]; }
    }
  }

And so on, adding new classes up to largest number parameters i would reasonably expect. Is there a better way to achieve this?


Are you re-inventing System.Tuple?

A tuple is a data structure that has a specific number and sequence of elements. An example of a tuple is a data structure with three elements (known as a 3-tuple or triple) that is used to store an identifier such as a person's name in the first element, a year in the second element, and the person's income for that year in the third element.


No, there is no better way in general, because you can't add multiple types into a generic list, if they don't derive from a common base class or implement the same interface.
However, your classes can be written a bit simpler, because you don't need the array, it doesn't add any value. On the contrary, it adds runtime and code complexity.

public class TypeSafe<T1>
{
    private readonly T1 arg1;

    public TypeSafe(T1 arg1)
    {
        this.arg1 = arg1;
    }

    public T1 Arg1
    {
        get { return arg1; }
    }
}

public class TypeSafe<T1, T2> : TypeSafe<T1>
{
    private readonly T2 arg2;

    public TypeSafe(T1 arg1, T2 arg2) : base(arg1)
    {
        this.arg2 = arg2;
    }

    public T2 Arg2
    {
        get { return arg2; }
    }
}


The way you do it is quite correct, I think. You can trick it a bit, however, not to have to define a lot of classes. Just if you need TypeSafe<T1, T2, T3>, use TypeSafe<TypeSafe<T1, T2>, T3>. You will lose in readability, though. As you'll have constructions like typeSafe.Arg1.Arg1 in your code. Also, you'll need to override Equals method.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号