2

In C#, you can write a function that takes any enumeration value as an argument by declaring the argument as type Enum, like so...

public enum FirstEnum
{
    A,
    B,
    C
}

public enum SecondEnum
{
    D,
    E,
    F
}

public void StoreValue(Enum key, object value)
{
    myDictionary[key] = value; <-- Uses the enum as a key
}

StoreValue(FirstEnum.A,  someItem); // Using the first enum type
StoreValue(SecondEnum.D, someItem); // Using the second enum type
StoreValue("Sam",        someItem); // Won't compile since 'Sam' is not an enum

Can you do something similar in Swift? I know you can declare the argument someEnum as a string and use it that way, but I'm trying to find out if it can be enforced to be an Enum like you can in C#.

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
  • Related: [Is there a way to make a function to accept any Enum types that have a rawValue of String?](http://stackoverflow.com/questions/32946576/is-there-a-way-to-make-a-function-to-accept-any-enum-types-that-have-a-rawvalue). – Martin R Aug 03 '16 at 18:12

2 Answers2

0

Not exactly. The whole point is strong typing.

You should create a protocol, make the enumeration(s) conform to it and use it in your interface definitions.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • I like the idea of the protocol approach. That may very well handle the same thing. Can you give an example though of how you'd use a protocol on an enum? That's new to me. – Mark A. Donohoe Aug 03 '16 at 17:56
  • just like anything else: http://stackoverflow.com/questions/24011170/how-to-make-an-enum-conform-to-a-protocol-in-swift – Wain Aug 03 '16 at 18:15
0

Following Wain's suggestion, you can write something like this:

enum FirstEnum: String
{
case
    A,
    B,
    C
}

enum SecondEnum: String
{
case
    D,
    E,
    F
}

//create a protocol
public protocol StringKeyEnum {
    var rawValue: String {get}
}
//make the enumeration(s) conform to it
extension FirstEnum: StringKeyEnum {}
extension SecondEnum: StringKeyEnum {}

var myDictionary: [String: AnyObject] = [:]
//use it in your interface definitions
public func storeValue(key: StringKeyEnum, value: AnyObject)
{
    myDictionary[key.rawValue] = value //<-- Uses the rawValue of enum as a key
}
let someItem = ""
storeValue(FirstEnum.A,  value: someItem) // Using the first enum type
storeValue(SecondEnum.D, value: someItem) // Using the second enum type
storeValue("Sam",        value: someItem) // Won't compile since 'Sam' is not a StringKeyEnum
Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
OOPer
  • 47,149
  • 6
  • 107
  • 142
  • @MarqueIV, it seems you have done so much with MY answer, in fact, I do not like my answer edited except correcting my errors or bad English. You should post your own answer. And one more thing you should know is that I intentionally have split enum declaration and its extension for protocol conformance, which is a way preferred by many programmers, including Apple's sample code authors. – OOPer Aug 04 '16 at 11:00
  • @MarqueIV, but the second thing you have mentioned in your comment, uniqueness, is really an essential improvement, as you know, you use that `key`s for the keys of a dictionary. And in such purpose, you should consider using `String.init(reflecting:)`. You can write your computational property `key` as `var key: String {return String(reflecting: self)}`. And I repeat, I do strongly expect you to revert all your editions, and post your own answer. I do not mind your moving "accept" marker to your own. – OOPer Aug 04 '16 at 11:11
  • Thanks for expressing that you have understood my feelings. I really appreciate it. And I do not want my edits to be taken as sort of "edit race" (often found in wiki-something). Please revert your edits when you have some time. And I really hope that your best answer (maybe written by yourself) would help many other developers. – OOPer Aug 04 '16 at 12:13