2012-04-15 4 views
2

Я хотел бы сделать статический класс с беглым интерфейсом, но я получаю сообщение об ошибке:Возвращения «это» в статическом методе

'this' is not valid in a static property, method ...

Вот мой код:

public static MyClass 
{ 
    private static StringBuilder builder; 
    private static StringBuilder RouteBuilder 
    { 
     get 
     { 
      if (builder == null) 
       builder = new StringBuilder(); 

      return builder; 
     } 
    } 

    public static MyClass Root() 
    { 
     RouteBuilder.Append("/"); 
     return this; 
    } 

    public static MyClass And() 
    { 
     RouteBuilder.Append("and"); 
     return this; 
    } 

    public static MyClass Something() 
    { 
     RouteBuilder.Append("something"); 
     return this; 
    } 
} 

Это позволяет мне делать MyClass.Root().And().Something();

Есть ли способ сделать это или обходным путем?

+2

Что бы вы хотели, чтобы «это» было в вашем статическом методе? – jalf

+1

Я написал [сообщение в блоге] (http://mattdavey.me/2012/03/08/practical-applications-of-the-adaptive-interface-pattern-the-fluent-builder-context/) о свободных интерфейсах компоновщика недавно, что могло бы помочь – MattDavey

ответ

11

Это невозможно. У вас не может быть экземпляр статического класса. Поскольку вы ставили MyClass как статический, не может быть никаких экземпляров. Не делайте это статический:

public class MyClass 
{ 
    private StringBuilder builder; 
    private StringBuilder RouteBuilder 
    { 
     get 
     { 
      if (builder == null) 
       builder = new StringBuilder(); 

      return builder; 
     } 
    } 

    public MyClass Root() 
    { 
     RouteBuilder.Append("/"); 
     return this; 
    } 

    public MyClass And() 
    { 
     RouteBuilder.Append("and"); 
     return this; 
    } 

    public MyClass Something() 
    { 
     RouteBuilder.Append("something"); 
     return this; 
    } 
} 

и тогда вы могли бы цепь:

var result = new MyClass().Root().And().Something(); 
1

возвращение RouteBuilder сделает трюк!

EDIT: так, извините

Для этих случаев, вы также можете просто сделать класс Extension

Say

public static class StringBuilderExtensions { 

    public static StringBuilder Root(this StringBuilder builder) { 
     Asserts.IsNotNull(builder); 
    builder.Append("/"); 
    return builder; 
    } 

    public static StringBuilder And(this StringBuilder builder) { 
    Asserts.IsNotNull(builder); 
    builder.Append("and"); 
    return builder; 
    } 
    //...etc 
} 

и использовать его как

var builder = new StringBuilder(); 
builder.Root().Append() 
+0

Это все еще плохо с вашими изменениями, так как возврат 'StringBuilder' не сообщает о том, что вы делаете. Метод, называемый 'And' на' StringBuilder', просто не имеет смысла. – CodesInChaos

+0

Хорошо, я согласен с тобой. Это всего лишь образец способа расширения.Класс MyClass также не так ясен;) Но я думаю, вы имеете в виду, что такие расширения лучше в «закрытом» классе, а не как чистые расширения StringBuilder, с которыми я тоже согласен. –

0

Я удивлен, что язык даже позволяет это - метод вы четко определили экземпляр экземпляра, но в том же определении класса вы заявили, что никогда не сможете создавать экземпляры его.

Вы все еще можете определить статические методы в нормальном классе. Вы можете заставить исполнитель всегда использовать свободно интерфейс, а не экземпляр MyClass себя:

  • Давать MyClass частного конструктора private MyClass(), которые могут быть вызваны только изнутри MyClass
  • маркировки MyClass, как sealed, чтобы предотвратить создание наследников, что выставить открытый конструктор.
0

Вы не можете использовать ключевое слово 'this' в статическом методе, потому что 'this' возвращает CURRENT INSTANCE класса. Но статические методы не принадлежат ни одному экземпляру (вместо этого они принадлежат самому классу) и, следовательно, не могут его вернуть.

Зачем вам нужен ваш класс и методы для статичности? Удаление всех статических ключевых слов заставит его работать. Если вы используете вместо этого Singleton pattern.

Смежные вопросы