2015-06-25 3 views
1

В настоящее время я пытаюсь написать расширения до Dynamic Linq. Для этого мне нужно добавить подпись метода к интерфейсу IEnumerableSignatures, расположенному во внутреннем классе ExpressionParser.Метод расширения для интерфейса во внутреннем классе

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

В то время как я мог бы добавить подпись к коду непосредственно, я предпочел бы определить это как метод расширения на интерфейс, чтобы сохранить исходный код в чистоте. Обычно, чтобы добавить метод DefaultIfEmpty, я хотел бы сделать что-то вроде этого:

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

Это дает ошибку доступа, хотя, потому что ExpressionParser является внутренним. Я уже пробовал с несколькими комбинациями уровня доступа для класса и метода.

Есть ли способ добавить метод расширения для такого интерфейса или мне нужно испортить исходный код?

Оказывается, даже если сам интерфейс является внутренним (или общедоступным), он не распознается динамическим linq. У меня все еще есть не найденное исключение во время выполнения. Таким образом, нет (очевидного) способа редактирования кода codeplex. [/ править]

+1

ли в той же сборке? – Silvermind

+0

Если это так. Сначала я хотел, чтобы dll из codeplex, но поскольку я добавил свой код непосредственно в исходный код, да, он в настоящее время. –

ответ

3

Вы не можете сделать это, так как IEnumerableSignatures частный интерфейс (он не имеет модификатор доступа и по умолчанию один является private) и нет никакого способа, чтобы получить доступ к нему из-за пределов ExpressionParser класса.

Но если вы можете изменить модификатор доступа к интерфейсу, тогда не должно быть никаких проблем, если вы правильно назначите модификаторы доступа.

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; } 
    } 
} 

Вы не можете скрыть свой сейф (частный/менее доступен/внутренний класс) внутри вашего дома (внешний класс), если вы дать ключ к кому-то.

Вы не можете использовать менее доступный класс в классе с более высокой доступностью. Например, используя частный класс в общедоступном. Вы не можете сделать общедоступный метод расширения для внутреннего класса, потому что вы не можете использовать общедоступный метод расширения вне сборки, потому что вы не можете получить доступ к внутреннему классу извне сборки!

+0

Я уже подозревал что-то вроде этого.Мне не нужен доступ к 'DefaultIfEmpty' напрямую, я просто хотел добавить подпись метода в место, которое легче поддерживать в случае обновлений кода из codeplex. –

1

Оба интерфейса IEnumerableSignatures и метод DefaultIfEmpty: private. Если вы сделаете их internal (или public), это сработает.

internal class ExpressionParser 
{ 
    internal interface IEnumerableSignatures { } 
} 

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

Это будет, конечно, никогда не будет работать, если ExpressionParser и Extension находятся в разных сборках, потому что они оба internal.

+1

«Никогда» - это сильное слово. Существует еще возможность определить сборку Friend. – Silvermind

+0

Он находится в той же сборке (в настоящее время). Но эта модификация мне не поможет. Если мне все равно придется модифицировать исходный код класса, я мог бы также добавить подпись напрямую;) –

+0

@ bone-idle Интерфейс 'private', поэтому он не будет виден нигде, кроме внутри класса ExpressionParser. Вы не можете написать метод расширения для того, что вы не видите. (Класс 'Extension' не знает' ExpressionParser.IEnumerableSignatures' существует) –

1

Нет Модификатор доступа такого же, как частные, так что просто добавить внутренний на то лицо

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

    } 
} 

И он должен работать

+0

Это не поможет мне. Если мне все равно придется изменять исходный код класса, я мог бы также добавить подпись напрямую;) –