При управлении доступом к внутреннему набору в c# - требуется Шаблон

Я думаю, что самый простой способ сопоставления символов, таких как

\^$.?*|+()[

, использует классы символов изнутри R. Рассмотрим, как очистить заголовки столбцов от файла данных, которые могут содержать пробелы и пунктуацию characters:

> library(stringr)
> colnames(order_table) <- str_replace_all(colnames(order_table),"[:punct:]|[:space:]","")

Этот подход позволяет нам вводить классы символов в соответствие с символами пунктуации, в дополнение к символам пробелов, что вам обычно нужно было бы избежать с помощью \\ для обнаружения. Вы можете узнать больше о классах символов в этой таблице ниже, и вы также можете ввести ?regexp, чтобы узнать больше об этом.

https://www.rstudio.com/wp -поперечник / добавления / 2016/09 / RegExCheatsheet.pdf

5
задан BIBD 26 November 2008 в 19:01
поделиться

8 ответов

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

Посмотрите превосходную серию Eric Lippert "Неизменности в C#": http://blogs.msdn.com/ericlippert/archive/tags/Immutability/C_2300_/default.aspx (необходимо прокрутить немного вниз),

3
ответ дан 14 December 2019 в 19:31
поделиться

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

Имейте частное List<T>

Имейте public void AddItem(T item) метод - каждый раз, когда Вы решаете сделать ту работу остановки, заставьте ее прекратить работать. Вы могли выдать исключение, или Вы могли просто заставить его перестать работать тихо. Зависит от того, на чем Вы начали там.

Имейте a public T[] GetItems() метод, который делает return _theList.ToArray()

1
ответ дан 14 December 2019 в 19:31
поделиться

Как многие из этих ответов шоу, существует много способов сделать сам набор неизменным.

Это прилагает больше усилий для хранения членов набора неизменными. Одна возможность состоит в том, чтобы использовать фасад/прокси (извините из-за отсутствия краткости):

class B
{
    public B(int data) 
    { 
        this.data = data; 
    }

    public int data
    {
        get { return privateData; }
        set { privateData = value; }
    }

    private int privateData;
}

class ProxyB
{
    public ProxyB(B b)   
    { 
        actual = b; 
    }

    public int data
    {
        get { return actual.data; }
    }

    private B actual;
}

class A : IEnumerable<ProxyB>
{
    private List<B> bList = new List<B>();

    class ProxyEnumerator : IEnumerator<ProxyB>
    {
        private IEnumerator<B> b_enum;

        public ProxyEnumerator(IEnumerator<B> benum)
        {
            b_enum = benum;
        }

        public bool MoveNext()
        {
            return b_enum.MoveNext();
        }

        public ProxyB Current
        {
            get { return new ProxyB(b_enum.Current); }
        }

        Object IEnumerator.Current
        {
            get { return this.Current; }
        }

        public void Reset()
        {
            b_enum.Reset();
        }

        public void Dispose()
        {
            b_enum.Dispose();
        }
    }

    public void AddB(B b) { bList.Add(b); }

    public IEnumerator<ProxyB> GetEnumerator()
    {
        return new ProxyEnumerator(bList.GetEnumerator());
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

Оборотная сторона этого решения - то, что вызывающая сторона будет выполнять итерации по набору объектов ProxyB, а не объектов B, которые они добавили.

1
ответ дан 14 December 2019 в 19:31
поделиться

Вы в основном не хотите выдавать ссылки на объекты класса B. Вот почему необходимо сделать копию объектов.

Я думаю, что это может быть решено с ToArray () метод Объекта списка. Необходимо создать глубокую копию списка, если Вы хотите предотвратить изменения.

Вообще говоря: большинство времен не стоит сделать копию для осуществления хорошего поведения, особенно когда Вы также пишете потребителю.

0
ответ дан 14 December 2019 в 19:31
поделиться
public class MyList<T> : IEnumerable<T>{

    public MyList(IEnumerable<T> source){
        data.AddRange(source);
    }

    public IEnumerator<T> GetEnumerator(){
        return data.Enumerator();
    }

    private List<T> data = new List<T>();
}

Оборотная сторона - то, что потребитель может изменить объекты, которые это получает от Перечислителя, решение состоит в том, чтобы сделать deepcopy частного Списка <T>.

0
ответ дан 14 December 2019 в 19:31
поделиться

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

internal class B : IB
{
    private string someData;

    public string SomeData
    {
        get { return someData; }
        set { someData = value; }
    }
}

public interface IB
{
    string SomeData { get; }
}
0
ответ дан 14 December 2019 в 19:31
поделиться

Править: Добавленная поддержка контекстов выпуска. Вызывающая сторона может только добавить элементы в контексте выпуска. Можно дополнительно осуществить тот только один контекст выпуска, может быть создан в течение времени жизни экземпляра.


Используя инкапсуляцию можно определить любой набор политик получить доступ к внутреннему члену парламента, не занимающему официального поста. Следующим примером является базовое внедрение Ваших требований:

namespace ConsoleApplication2
{
    using System;
    using System.Collections.Generic;
    using System.Collections;

    class B
    {
    }

    interface IEditable
    {
        void StartEdit();
        void StopEdit();
    }

    class EditContext<T> : IDisposable where T : IEditable
    {
        private T parent;

        public EditContext(T parent)
        {
            parent.StartEdit();
            this.parent = parent;
        }

        public void Dispose()
        {
            this.parent.StopEdit();
        }
    }

    class A : IEnumerable<B>, IEditable
    {
        private List<B> _myList = new List<B>();
        private bool editable;

        public void Add(B o)
        {
            if (!editable)
            {
                throw new NotSupportedException();
            }
            _myList.Add(o);
        }

        public EditContext<A> ForEdition()
        {
            return new EditContext<A>(this);
        }

        public IEnumerator<B> GetEnumerator()
        {
            return _myList.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public void StartEdit()
        {
            this.editable = true;
        }

        public void StopEdit()
        {
            this.editable = false;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            using (EditContext<A> edit = a.ForEdition())
            {
                a.Add(new B());
                a.Add(new B());
            }

            foreach (B o in a)
            {
                Console.WriteLine(o.GetType().ToString());
            }

            a.Add(new B());

            Console.ReadLine();
        }
    }
}
0
ответ дан 14 December 2019 в 19:31
поделиться

Самым простым, о котором я могу думать, является возврат версия только для чтения базового набора, если редактирование больше не позволяется.

public IList ListOfB
{
    get 
    {
        if (_readOnlyMode) 
            return listOfB.AsReadOnly(); // also use ArrayList.ReadOnly(listOfB);
        else
            return listOfB;
    }
}

Лично, хотя, я не выставил бы базовый список клиенту и просто предоставил бы методы для добавления, удаления и перечисления экземпляров B.

0
ответ дан 14 December 2019 в 19:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: