1

I am currently trying to write extensions to Dynamic Linq. For that I need to add a method signature to the IEnumerableSignatures interface located in the internal class ExpressionParser.

internal class ExpressionParser
{
    interface IEnumerableSignatures
    {
        [...]
    }
}

While I could add the signature to the code directly, I'd rather define this as an extension method to the interface, to keep the original code clean. Usually, to add the method DefaultIfEmpty, I would do something like this:

internal static class Extension 
{
    static void DefaultIfEmpty(this ExpressionParser.IEnumerableSignatures sig);
}

This gives an access error though, because ExpressionParser is internal. I have already tried with several combinations of access level for the class and method.

Is there a way to add an extension method to such an interface or do I have to mess with the original code?

[edit] Turns out that, even when making the interface itself internal (or public for that matter), it is not recognized by dynamic linq. I still got some not-found exception on runtime. So there's no (obvious) way around editing the codeplex code. [/edit]

Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74
hakai
  • 329
  • 3
  • 13

3 Answers3

6

You can not do that since IEnumerableSignatures is a private interface (it has no access modifier and the default one is private) and there is no way to access it from outside of ExpressionParser class.

But if you can change the interface access modifier then there should be no problem if you assign the access modifiers correct.

internal static class Extension
{
    internal static int Foo(this ExpressionParser.IEnumerableSignatures b)
    {
        return b.Ib;
    }
}

internal class ExpressionParser
{
    public int Ia { get; set; }
    internal interface IEnumerableSignatures
    {
        int Ib { get; set; }
    }
}

You can not hide your safe (private/less accessible/inner class) inside your house (outer class) if you give the key to someone.

You can not use a less accessible class in a class with higher accessibility. For example using a private class in a public one. You can not make a public extension method for a class that is internal because you can not use the public extension method outside the assembly because you can not access the internal class from outside of assembly!

Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74
  • I already suspected something like this. I don't need access to `DefaultIfEmpty` directly, I just wanted to add the method signature in a place that is easier to maintain in case of updates to the code from codeplex. – hakai Jun 25 '15 at 09:30
1

Both the interface IEnumerableSignatures and the method DefaultIfEmpty are private. If you make them internal (or public) it will work.

internal class ExpressionParser
{
   internal interface IEnumerableSignatures { }
}

internal static class Extension
{
    internal static void DefaultIfEmpty(this ExpressionParser.IEnumerableSignatures sig) {
        ...
    }
}

It will of course never work if ExpressionParser and Extension are in different assemblies, because they are both internal.

Dennis_E
  • 8,751
  • 23
  • 29
  • 1
    'Never' is a strong word. There is still the option to define a Friend assembly. – Silvermind Jun 25 '15 at 09:13
  • It is in the same assembly (currently). But that modification won't help me really. If I have to modify the source code of the class anyway, I could also add the signature directly ;) – hakai Jun 25 '15 at 09:24
  • @bone-idle The interface is `private`, so it won't be visible anywhere but inside the `ExpressionParser` class. You cannot write an extension method for something you cannot see. (The `Extension` class doesn't know `ExpressionParser.IEnumerableSignatures` exists) – Dennis_E Jun 25 '15 at 09:26
1

No access modifier is the same as private, so just add internal to the inter face

internal class ExpressionParser 
{
    internal interface IEnumerableSignatures
    {
    }
}
internal static class Extension
{
    static void DefaultIfEmpty(this ExpressionParser.IEnumerableSignatures sig)
    {

    }
}

And it should work

  • That won't help me really. If I have to modify the source code of the class anyway, I could also add the signature directly ;) – hakai Jun 25 '15 at 09:24