Reputation: 1946
I'm implementing a method in C# that takes a single argument of type object
, e.g. SomeMethod(object argument)
. I need to pass a collection of multiple objects of varying type to this method. I can't change the method signature because of interface restrictions.
I was thinking of sending an object array, object[] myArray = new object[2]
, but I want to strongly type each element of the array if possible. For example, I have two objects, one of type Foo
and the other of Bar
. I want to guarantee that myArray[0]
is Foo
and myArray[1]
is Bar
.
How would I do this? Would another collection type or creating a special class make more sense?
UPDATE: All good answers. Tuple looks the most generic way but as I said in the comment, I'm limited to 3.5. A struct would work but after a little research on using structs vs classes as arguments, there is a slight performance hit if you use a larger struct. (Source - see Benchmark section). So I'm going to go with a class. Thank you all!
Upvotes: 4
Views: 1029
Reputation: 43698
You might be better off with a Tuple<>
, for example:
Foo foo = new Foo();
Bar bar = new Bar();
Tuple<Foo, Bar> fooBar = new Tuple(foo, bar);
SomeMethod(fooBar);
But without further info on your code, its hard to tell whether that would fit your needs better than an object[]
.
Upvotes: 1
Reputation: 112279
Create a class or struct that reflects your need
public class FooBar
{
public Foo Foo { get; set; }
public Bar Bar { get; set; }
}
Then call your method like this
SomeMethod(new FooBar { Foo = foo, Bar = bar });
Implement it like this
public SomeMethod(object argument)
{
var fooBar = argument as FooBar;
if (fooBar != null) {
Foo foo = fooBar.Foo;
Bar bar = fooBar.Bar;
...
}
}
Upvotes: 1
Reputation: 28752
I want to guarantee that myArray[0] is Foo and myArray[1] is Bar
An Array
is collection of objects of some type. So you cannot guarantee this. The only way to do this is to create a composite type, a struct
or a class
.
But if your signature SomeMethod(object argument)
is fixed, you would still not be able to guarantee that statically inside that method. The best you can do is to externally make sure you are passing argument of the correct type.
Upvotes: 2
Reputation: 754545
The only way to safely store a set of unrelated types in a collection is to use an intermediate type which restricts values to those types and store that type in the collection. It's a poor man's discriminated union.
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
Upvotes: 2