如何使用不同类型的单个元素创建类型安全的数组或集合?

时间:2012-04-26 16:47:34

标签: c# arrays generics

我正在C#中实现一个方法,它采用object类型的单个参数,例如SomeMethod(object argument)。我需要将不同类型的多个对象的集合传递给此方法。由于接口限制,我无法更改方法签名。

我正在考虑发送一个对象数组object[] myArray = new object[2],但是如果可能的话我想强烈地键入数组的每个元素。例如,我有两个对象,一个是Foo类型,另一个是Bar。我想保证myArray[0]FoomyArray[1]Bar

我该怎么做?另一个集合类型或创建特殊类会更有意义吗?

更新:所有好的答案。元组看起来是最通用的方式,但正如我在评论中所说,我只限于3.5。一个结构可以工作,但经过一些关于使用结构与类作为参数的研究之后,如果使用更大的结构,会有轻微的性能损失。 (Source - 参见基准部分)。所以我打算上课。谢谢大家!

4 个答案:

答案 0 :(得分:2)

在集合中安全存储一组不相关类型的唯一方法是使用中间类型,该类型将值限制为这些类型并将该类型存储在集合中。这是一个穷人的歧视联盟。

sealed class FooOrBar {
  public readonly Foo Foo;
  public readonly Bar Bar;
  public bool IsFoo { 
    get { return Foo != null; }
  }
  public bool IsBar {
    get { return Bar != null; }
  }
  public FooOrBar(Foo f) {
    Foo = f;
  }
  public FooOrBar(Bar b) {
    Bar = b;
  }
  public static implicit operator FooOrBar(Foo f) {
    return new FooOrBar(f);
  }
  public static implicit operator FooOrBar(Bar b) {
    return new FooOrBar(b);
  }
}

FooOrBar[] array = new FooOrBar[2];
array[0] = new Foo();
array[1] = new Bar();
array[2] = "test";  // Fails to compile

答案 1 :(得分:2)

  

我想保证myArray [0]是Foo而myArray [1]是Bar

Array是某种类型的对象的集合。所以你不能保证这一点。执行此操作的唯一方法是创建复合类型,structclass

但是如果您的签名SomeMethod(object argument)已修复,您仍然无法在该方法内静态保证。您可以做的最好的事情是从外部确保传递正确类型的参数。

答案 2 :(得分:1)

创建一个反映您需求的类或结构

public class FooBar
{
    public Foo Foo { get; set; }
    public Bar Bar { get; set; }
}

然后像这样调用你的方法

SomeMethod(new FooBar { Foo = foo, Bar = bar });

像这样实施

public SomeMethod(object argument)
{
    var fooBar = argument as FooBar;
    if (fooBar != null) {
        Foo foo = fooBar.Foo;
        Bar bar = fooBar.Bar;
        ...
    }
}

答案 3 :(得分:1)

使用Tuple<>可能会更好,例如:

Foo foo = new Foo();
Bar bar = new Bar();
Tuple<Foo, Bar> fooBar = new Tuple(foo, bar);
SomeMethod(fooBar);

但如果没有关于代码的进一步信息,很难判断这是否比object[]更符合您的需求。