C #, Как вы можете сделать объект реинициализировать себя? - PullRequest
2 голосов
/ 23 января 2009

Хорошо, в Perl вызывать повторную инициализацию объекта легко, поскольку он представлен назначаемой ссылкой или указателем. C #, похоже, не нравится это.

Я хотел создать подкласс System.Text.RegularExpressions.Regex, шаблон которого можно изменить без использования новых объектов и потребления памяти для каждого. (частные инициализированные ссылки не позволят мне запустить его снова, поэтому я попытался воссоздать объектную ссылку).

Можно ли обойтись без создания полной обертки вокруг родительского объекта с повторной реализацией каждого метода для указания на частный объект регулярного выражения, который повторно инициализируется для каждого нового использования? Есть ли лучший способ?

public class m_Regex : System.Text.RegularExpressions.Regex{

    public m_Regex(string pattern): base (pattern){

    }

    public void Pattern(string pattern){
        this = new m_Regex(pattern);
    }   
}

Ответы [ 6 ]

2 голосов
/ 23 января 2009

Причина, по которой класс System.Text.RegularExpressions.Regex ведет себя таким образом, заключается в том, что он неизменен. Таким образом, вы не можете изменить шаблон после создания объекта Regex. Короче говоря, нет способа сделать то, что вы хотите сделать, то есть повторно инициализировать существующий объект с новым шаблоном. Если вы хотите изменить шаблон, по определению вам придется создать новый объект Regex.

2 голосов
/ 23 января 2009

Я не уверен, какую именно проблему вы пытаетесь решить. Если вас беспокоит объем используемой памяти, возможно, из-за быстрого создания / удаления объектов Regex, тогда вы можете сделать так, чтобы ваша оболочка реализовала IDisposable и поместила их в блок using, чтобы ресурсы высвобождались быстрее. Если количество объектов Regex довольно мало, то я не уверен, что я бы слишком беспокоился об этом. Как только объект выходит из области видимости, его можно собирать. Если объект Regex исправлен, вы также можете подумать о создании статических экземпляров каждого в «фабрике регулярных выражений», которую можно использовать снова и снова.

1 голос
/ 23 января 2009
//First use
myregex = new RegEx("^Pattern$");    
// later on in the code, i need to change pattern
// this call is different to the first, and i can't tell why..
myregex = myregex.Pattern("^NewPattern$");

Если бы я взглянул на код, в котором использовался этот шаблон, я бы сразу перешел к реализации .Pattern, чтобы понять, почему «следующее» использование myregex отличается от первого. Я ожидал бы, что на конструкцию нового регулярного выражения повлияло состояние текущего экземпляра регулярного выражения (хотя я пытался и не смог понять, как это повлияет).

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

Что касается вопроса GC, GC может быть принудительно запущен с вызовом GC.Collect (), но запрос коллекции является исключительной вещью и не должен вызываться как правило.

0 голосов
/ 23 января 2009

После некоторого оскорбления я обнаружил, что это делает то, что я хочу с некоторыми (незначительными) семантическими различиями

`открытый класс m_Regex: System.Text.RegularExpressions.Regex {

    public m_Regex(string pattern): base (pattern){

    }

    public m_Regex Pattern(string pattern){

        return new m_Regex(pattern);
    }


}`

Так что теперь я могу использовать шаблон, чтобы «переопределить» текущее регулярное выражение, назначив новую ссылку на объект для переменной хранения вместо замены самого экземпляра. И теперь (предположительно) предыдущая ссылка на регулярные выражения помечена для GC, так как никто больше не использует ее, а более приятный и самодокументированный

myregex = myregex.Pattern ("^ NewPattern $"); может использоваться для создания функциональной иллюзии регулярного выражения изменения шаблона, хотя я думаю, что я все же предпочел бы иметь возможность просто вызывать элемент и вызывать его полностью за сценой.

Так я прав? Соберет ли GC все используемые регулярные выражения, следуя этой схеме? Будет ли это так, даже если текущая реализация находится в области видимости? Когда происходит GC?

0 голосов
/ 23 января 2009

Интересно, есть ли хороший внешний конкурент Regex для встроенного .NET, который вы могли бы использовать для этого.

Может быть = http://www.codeguru.com/Cpp/Cpp/string/regex/article.php/c2779/

0 голосов
/ 23 января 2009

C # не поддерживает такой синтаксис. Фактически, если вы попытаетесь скомпилировать свой код, вы получите ошибку компиляции, в которой говорится: «это свойство только для чтения». К сожалению, сегодня тебе не повезло. :)

Другой способ - не основывать свой класс на регулярном выражении, а иметь класс-оболочку. Например.

public class Wrapper
{
 private Regex _regex;
 public Wrapper(string pattern)
 {
  _regex = new Regex(pattern);
 }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...