2

When attempting to pass in an array of a specific enum type as a function argument via params object[], I am unable to pass in an actual array without casting to object[] first. But if I do so I do not have access to the original enum type.

Given the enum and function shown below, this works fine:

var works = SomeFunction(Season.Fall, Season.Winter);

However, this fails because it cannot implicitly convert to object, so it passes array as first argument as opposed to individual arguments:

var seasons = new Season[] {Season.Fall, Season.Winter};
var fail = SomeFunction(seasons);

It also cannot cast to object[] because then later it is unable to determine the original type. How can I use a predetermined array to pass it in?

[Flags]
public enum Season : byte
{
    None = 0,
    Spring = 1,
    Summer = 2,
    Fall = 4,
    Winter = 8
}

...

public Something SomeFunction(params object[] values) 
{
     ...
     foreach (var value in values)
     {
          var type = value.GetType();
          ...
     }
}

UPDATE: it works to convert the Season[] array to object[], but that seems hokey:

var seasons = new object[original.Length];
for (int i = 0; i < original.Length; i++)
{
       seasons[i] = original[i];
}
5
  • 1
    pass in the enum type as well? not sure what you are actually asking here.... Commented Jun 14, 2015 at 3:52
  • did you try: params Season[] values? Commented Jun 14, 2015 at 3:53
  • Using third-party API so unable to change the argument type. Commented Jun 14, 2015 at 3:56
  • It works to convert the Season[] array to object[]. See update. Commented Jun 14, 2015 at 3:59
  • what version of .NET @Ted? Commented Jun 14, 2015 at 4:07

4 Answers 4

1

It's as simple as converting an object[] containing the enums as opposed to casting the array:

var original = new Season[] {Season.Fall, Season.Winter};

var selectedSeasons = new object[original.Length];
for (int i = 0; i < original.Length; i++)
{
       selectedSeasons[i] = original[i];
}

var works = SomeFunctionWithObjectParamsArgs(selectedSeasons);

Yes, ultimately changing the function signature to be generic would be best, but doesn't apply in my case (third-party API).

Sign up to request clarification or add additional context in comments.

Comments

0

Consider using the Cast<>() LINQ Method instead of a for loop, this looks cleaner:

var seasons = SomeFunction(seasons.Cast<object>().ToArray());

There's no other way you can cast an array of value types to an array of objects, you can't leverage array covariance in this case because it only works between arrays of compatible reference types.

3 Comments

I swear I tried that, but obviously not, as it does exactly what the loop does. And yes, much cleaner.
I was preparing a live demo just to show you were wrong :) ideone.com/nAZTDY
I admit it! I admit it! Thanks. Surprising I've never run into this issue before (if can't implicitly convert because can't use array covariance, it passes it as the first arg instead of array of args) but now I know.
0

This code compiles in .NET 3.5, 4.0, and 4.5. Are you getting a compiler error when you build?

class Program
{
    static void Main(string[] args)
    {
        var p = new Program();
        p.SampleFunc(Seasons.Winter, Seasons.Fall);
    }

    void SampleFunc(params object[] elements)
    {
        foreach(var element in elements)
        {
            if (element is Seasons)
            {
                // do something.
            }
        }
    }

    enum Seasons
    {
        Winter, Spring, Summer, Fall
    }
}

4 Comments

Can't change SomeFunction as it's a third-party API.
ah. OK. well is it abstract and you're implementing it? or is it virtual? how are you affecting what's going on within that method?
Technically, I could change it, but the issue is knowing what to do if couldn't. It turns out just need to convert (not cast) the original array.
as long as you have a solution. go with it.
0

I think this does it...

public enum MyEnum
{
    EnumValue1,
    EnumValue2,
    EnumValue3
}

class Program
{
    static void Main(string[] args)
    {
        var TheEnumList =(from list in Enum.GetValues(typeof (MyEnum)).Cast<int()
                          select new {EnumValueInstance = (MyEnum) list})
                         .ToList();
        TheEnumList.ForEach(enumItem => Console.WriteLine(enumItem.EnumValueInstance));
        var result = SomeFunction(TheEnumList);
        Console.WriteLine(result);
        Console.ReadKey();
    }

    public static MyEnum SomeFunction(params object[] values)
    {
        dynamic obj = values[0];
        return obj[0].EnumValueInstance;
    }
}

2 Comments

Sorry, but the issue is have an array of enums that I'm passing into a function with params object[] as the argument (nothing to do with converting to a list of enum values).
I solved for this part "But if I do so, then I do not have access to the original enum type." You will have access to that property within "SomeFunction" via the "EnumValueInstance" property. That sounded like your primary challenge. You will have to use reflection to access it...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.