2

I built a extension method for Enums (Enumerations) - , name it, say GetEnumSecondName

static string GetEnumSecondName(this Enum myEnumInstance)    {...}

Now, I have a generic method, that should take a Enumeration and return all the second names for that type.

List<string> GetSecondNames<T : ?T:Enum ? >()
{ 
  // ...

  foreach T member in GetAllMembers<T>()
    // should work only for Enum instances
    resultList.Add(member.GetEnumSecondName()); 

  // ...
}

Is there a workaround to do it?

Edit:

As I understood (thanks to Jon Skeet), C# does not support thins kind of constraint. If there are any VB.NET expert to confirm that "ordinary" VB.NET does not support it either. Thanks.

serhio
  • 28,010
  • 62
  • 221
  • 374
  • possible duplicate of [Interesting "params of ref" feature, any workarounds?](http://stackoverflow.com/questions/1776020/interesting-params-of-ref-feature-any-workarounds) – nawfal Mar 02 '13 at 20:52

1 Answers1

7

Yes, there's a workaround. You may not like it though. You have to rewrite the IL to express the constraint you want - because the CLR allows it, but C# doesn't. (The compiler respects the constraint; it just doesn't let you express it in C# code.)

I have a project called Unconstrained Melody which does exactly this, introduced in a blog post.

It's regrettable that you can't express this, and maybe it'll be fixed in a future version of the language. For now, IL rewriting is all there is as far as I know.

EDIT: I've just tried the constraint you'd want in VB:

Foo(Of T As { System.Enum, Structure }) (...)

And the compiler complains with:

error BC32061: 'Enum' cannot be used as a type constraint.

So no, you can't do it in VB either. Oddly enough, the web page about that error doesn't mention the restriction...

EDIT: To anyone wanting to play with Unconstrained Melody, there are a few steps required to get it working:

  • You need to make sure you have an appropriate SDK directory as referred to by ConstraintChanger\Program.cs. In particular, check in \Program Files\Microsoft SDKs\Windows to see what version you've got - and change Program.cs appropriately
  • Critically, you need a directory called "Rewritten" at the top level (i.e. alongside lib)
  • If you're using VS2010 you'll need to go through the project upgrade at the start

Once all of that is correct, you should just be able to hit Ctrl-Shift-B and get a working build. Do not remove and replace the project references - the test assembly needs to refer to the rewritten one, not the project it's created from.

I'll attempt to address some of these issues tonight - and possibly even create a Nuget package...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    @serhio: If you work in VB, why did your write your question in C#? Way to waste people's time... I don't know whether VB allows it. Read the VB spec to check. – Jon Skeet Aug 17 '11 at 14:37
  • 2
    VB doesn't afaik, but F# supports it. – Mark H Aug 17 '11 at 14:38
  • @Jon Skeet: I wrote it in C#, because I write all my examples in C#. The answer from people came faster if I Write in C# if I write it in Vb.NET. And I didn't specify the C# tag... – serhio Aug 17 '11 at 14:40
  • @serhio: But how is that good if the answers aren't then useful? You should *at least* have mentioned that you were really interested in VB. – Jon Skeet Aug 17 '11 at 14:40
  • @Jon: Almost any of questions here are not language specific. I didn't know *a priori* that this constraint could be language specific... – serhio Aug 17 '11 at 14:43
  • @serhio: No, *lots* of the questions here are language specific. It's bad enough to not mention the language you're interested in - it's downright rude to give code in one language when you're only interested in a different one. – Jon Skeet Aug 17 '11 at 14:46
  • @Jon: I understood. In my practice I have not almost any question of that kind. But I will pay attention to this in the future. – serhio Aug 17 '11 at 14:48
  • @Jon: actually I find it great that he took time and wrote the example in C#. I agree with him that there's a lot of more answers for code written in C# than VB.net (although I haven't checked any statistics). I don't think that he answered your comments in a rude way, it's rather you that answer him with an attitude. – jgauffin Aug 17 '11 at 14:55
  • @jgauffin: Because I object to my time being wasted. If someone asks me a question, I expect *that question* to be what they want an answer to - so it annoys me when I put in effort answering exactly that question, only to find out that they *really* wanted something else. Serhio knew to start with that he wanted an answer in VB - I didn't. Suppose this *was* allowed in VB - I could have tried that quickly instead, and not written any of the stuff about C#. All the C# bits would be irrelevant, and therefore a waste of my time. (Continued) – Jon Skeet Aug 17 '11 at 14:57
  • *As it happens* in this case the restrictions are the same, but there's no reason to suppose they would be, or that the answer would be the same. There are plenty of topics where this would apply - lambda expressions, anonymous types, iterator blocks, dynamic typing etc. I view it as disrespectful of potential answerers' time (not just me - anyone else answering the question too) to have relevant information and not bother including it in the question. – Jon Skeet Aug 17 '11 at 14:59
  • the google project unconstrained don't work on my machine: The type 'UnconstrainedMelody.Test.BitFlags' cannot be used as type parameter 'T' in the generic type or method 'UnconstrainedMelody.Flags.IsFlags()'. There is no boxing conversion from 'UnconstrainedMelody.Test.BitFlags' to 'UnconstrainedMelody.IEnumConstraint'. In ...UnconstrainedMelody\UnconstrainedMelody.Test\FlagsTest.cs 11 27 UnconstrainedMelody.Test – serhio Aug 17 '11 at 15:01
  • @serhio: I suspect you're trying to do something against the un-rewritten IL... or you haven't fixed the code to use the correct rewriter location. Have you just opened the project and tried to build it as-is? – Jon Skeet Aug 17 '11 at 15:02
  • @Jon: I tried first, but no success I saw a icon (!) on the unconstrainedMelody reference, so I removed it and replaced with the project (unconstrainedMelody) reference. Didn't help. I tried to build just the "UM" project, but "The command "...UnconstrainedMelody\\ConstraintChanger\bin\Debug\ConstraintChanger"" exited with code 1." I converted the solution in VS 2010... – serhio Aug 17 '11 at 15:07
  • @Jon skeet: All I'm saying is that his intentions was good. You of all should know that it's not easy to write a good question with all relevant details. At least I have written several answers which answered something else than the OP really wanted due to incorrect or missing details. But that's not a reason to give an attitude, is it? After all, we do answer questions because we want to, not because we are forced to. – jgauffin Aug 17 '11 at 15:07
  • @serhio: Ah. No, you absolutely should *not* have removed that reference. It's deliberately set to the rewritten code, which needs to be built first. You need to adjust ConstraintChanger to refer to the relevant ilasm binary, IIRC. – Jon Skeet Aug 17 '11 at 15:09
  • @jgauffin: Every possible relevant detail can be hard to work out. Which language you're interested in *isn't* hard to work out or state. And I answer questions because I want to help people - which makes it frustrating when the person I'm *trying to help* wastes my time. That time could be spent helping someone who *doesn't* write a question in one language but then ask for an answer in a different one. Would you feel any differently if you'd spent an hour on a long answer which turned out to be entirely useless to the person you were answering? – Jon Skeet Aug 17 '11 at 15:10
  • without removing the reference, 65 errors, firrst one: Error 1 The name 'Enums' does not exist in the current context C:\Documents and Settings\me\Desktop\test\UnconstrainedMelody-0.0.0.2-src\UnconstrainedMelody\UnconstrainedMelody.Test\EnumsTest.cs 13 32 UnconstrainedMelody.Test – serhio Aug 17 '11 at 15:11
  • ok, thank you. Don't spend your time with me man, if you don't want! I don't force you to answer me! – serhio Aug 17 '11 at 15:12
  • @serhio: Yes, you first need to build the constraint changer, then run it successfully on the non-test assembly (which is part of the build). I suspect that *just* fixing the local of ilasm.exe in ConstraintChanger and then doing Rebuild Solution would have sorted it out... – Jon Skeet Aug 17 '11 at 15:13
  • @serhio: I have no objection to spending time helping people. I have an objection to people not taking the time when they ask for help to thinking what might be relevant, and presenting that information accordingly. I'll try building Unconstrained Melody from scratch on my own laptop and update this answer with instructions... – Jon Skeet Aug 17 '11 at 15:15
  • I built successfully the ConstraintCharger, but I don't understand the "then run it successfully on the non-test assembly" (how to "run" the *ConstraintChanger* "on the" *UnconstrainedMelody*) – serhio Aug 17 '11 at 15:27
  • @serhio: it should run automatically in the build. It sounds like you saw it fail to run properly earlier on. – Jon Skeet Aug 17 '11 at 15:40
  • @serhio: I've edited the answer with the steps you need to get it working. Hope that helps. – Jon Skeet Aug 17 '11 at 16:18