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

本文关键字:元素 单个 类型安全 数组 集合 同类型 何创建 创建 | 更新日期: 2023-09-27 18:32:17

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

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

我该怎么做?另一种集合类型或创建特殊类是否更有意义?

更新:所有好的答案。元组看起来是最通用的方式,但正如我在评论中所说,我仅限于 3.5。结构可以工作,但是在对使用结构与类作为参数进行了一些研究之后,如果使用较大的结构,则性能会略有下降。(来源 - 请参阅基准部分)。所以我要去上课。谢谢大家!

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

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

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

但是,如果您的签名SomeMethod(object argument)是固定的,您仍然无法在该方法中静态地保证这一点。你能做的最好的事情就是从外部确保你传递的参数是正确的类型。

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

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

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

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

您可能最好使用Tuple<>,例如:

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

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