20

I'm playing with ScriptCS (which is awesome!) but I couldn't figure out how to define an extension method within a .csx script file.

Take this example:

using System.IO;

public static class Extensions
{
    public static string Remove(this string source, params string[] toRemove)
    {
        foreach(var r in toRemove)
        {
            source = source.Replace(r,"");
        }
        return source;
    }
}

string[] entries = 
    Directory
        .GetFiles(
            @"C:\Users\blah\blah",
            "*.mp4",
            SearchOption.AllDirectories)
    .Select( p => p.Remove("Users"))
    .ToArray();

foreach(var e in entries)
{
    Console.WriteLine(e);
}

This yields the error:

error CS1109: Extension methods must be defined in a top level static class; Extensions is a nested class

I'm guessing that ScriptCS wraps the csx in some class which is causing extensions to be nested, is there any way around this?

TJB
  • 13,367
  • 4
  • 34
  • 46
  • 1
    This is a limitation in Roslyn. See: http://social.msdn.microsoft.com/Forums/en-US/roslyn/thread/7c0a18eb-d37a-40e2-a26c-edb59b8f5cf3/. So currently you can't define extension methods in `.csx` files. You need to put them in a dll and reference that the dll. – nemesv Jun 05 '13 at 20:14
  • @nemesv this looks answer-worthy =) Thank you – TJB Jun 05 '13 at 20:50
  • 2
    Related: https://stackoverflow.com/questions/42285150/how-do-you-have-shared-extension-methods-in-azure-functions-without-nesting-clas – Maxim Kamalov Mar 21 '18 at 19:53

3 Answers3

21

I feel your pain.

Actually this is a limitation of Roslyn currently as it wraps everything into a class even if it is another class.

I've talked to the Roslyn team however and they are going to support extension methods soon.

Glenn Block
  • 8,463
  • 1
  • 32
  • 34
  • 3
    Run into this issue 3 years later: how should we interpret the word "soon"? – fra Dec 11 '16 at 04:43
  • That's a great question. We're about to update to the latest version of Roslyn (2.0). I'll find out if that has added support for extension methods within csx. – Glenn Block Feb 22 '17 at 09:24
  • 6
    Update on this. I confirmed in the latest Roslyn, top level extension methods are supported, so we should be able to get this to work for scriptcs when we release on Roslyn 2.0 (which should be months hopefully) – Glenn Block Feb 23 '17 at 16:18
13

Good news! It is now supported in C# script files (.csx)

But you have to declare an extension method on top level:

static string MyToLowerExtension(this string str)
{
    return str.ToLower();
}

Do not declare it in a static class:

// this will not work!
public static class MyExtensionsClass
{
    static string MyToLowerExtension(this string str)
    {
        return str.ToLower();
    }
}
Artemious
  • 1,980
  • 1
  • 20
  • 31
  • tried a couple of times. didnt work. can you give an complete sample and versions of scriptcs and used framework? – Chris Nov 09 '18 at 19:55
  • @Chris sorry, I thought the question was about c# script (like c# Interactive window in Visual Studio), but now I see it's regarding some other technology – Artemious Nov 10 '18 at 14:38
  • Well, how do you make it run? (Console please) – Chris Nov 10 '18 at 15:16
  • sorry, I don't know how about CLI. I prefer Visual Studio. It is under View menu - Other windows - C# Interactive – Artemious Nov 10 '18 at 15:38
2

Unfortunately, because compiling something on the fly requires a class, scriptcs was designed to take the raw code that mattered and wrap it in a class. You would need to modify a version of scriptcs for your needs -or consider contributing to the project.

However, I too love scriptcs and think it's one of the most fantastic projects out there today!

I too tried this early on when using scriptcs and my heart broke when it didn't work. If I had more bandwidth I'd contribute this addition on my own.

AFAIK this is not a limitation with Roslyn.

Mike Perrenoud
  • 66,820
  • 29
  • 157
  • 232