Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
0 / 0 / 0
Регистрация: 04.02.2025
Сообщений: 53

Запрет редактирования элементов извне класса

25.08.2025, 01:13. Показов 2652. Ответов 23
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Столкнулся со следующей проблемой.
В классе myclass работаю с Ethernet-ом. По приходу очередного кадра извлекаю из него информацию и на основе неё создаю объект класса cell и помещаю его в список List. Этот список передаётся во вне для отображения его в интерфейсе программы на экране.
Задача состоит в том что хотелось бы заблокировать за пределами класса myclass как редактировать сам список так и поля элементов списка. Притом одно поле Check для изменения должно быть доступно.
Никак не могу понять как это сделать, спрашивал у нейросити - рабочих вариантов не выдаёт, складывается ощущение что такого вообще добиться нельзя.

Привожу код для наглядности. В коде метод CreateList() вызывается из метода Main() для упрощения примера, в рабочей программе он вызывается при приёме Eth-какдра.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using System.Collections.Generic;
 
class myclass
{
    public class cell
    {   
        public int Number;
        public string Type;
        public bool Check;
    }
    
    public List<cell> Cells = new List<cell>();
    
    public void CreateList()
    {
        Cells.Add(new cell());
        Cells.Add(new cell());
        
        Cells[0].Number = 1;
        Cells[0].Type = "A";
        Cells[0].Check = false;
        
        Cells[1].Number = 2;
        Cells[1].Type = "B";
        Cells[1].Check = false;
    }
}
 
class Program
{   static void Main()
    {
        myclass MyObj = new();
        MyObj.CreateList();
 
        foreach(myclass.cell Cell in MyObj.Cells)
        {
            Console.WriteLine($" {Cell.Number}, {Cell.Type}, {Cell.Check}");
        }
 
        MyObj.Cells.Add(new myclass.cell());    //изменение состава списка не должно работать!!!
        MyObj.Cells[0].Number = 1000;           //изменения элементов списка не должно работать!!!
        MyObj.Cells[0].Check = true;            //кроме одного, этот менять можно!
    }
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.08.2025, 01:13
Ответы с готовыми решениями:

Привязка к свойству и возможность редактирования извне
Всем доброго времени суток! Возникла дилемма. У меня есть 3 TextBox, при изменении TextBox2.Text...

Запрет редактирования DataGridView
Как запретить редактировать определенные ячейки?

Запрет редактирования DataGridView на форме
Собственно вопрос, как можно запретить редактирование динамически созданной DGV непосредственно с...

23
Эксперт .NET
 Аватар для Usaga
14072 / 9289 / 1347
Регистрация: 21.01.2016
Сообщений: 34,870
25.08.2025, 06:00
Цитата Сообщение от Jack0v Посмотреть сообщение
Задача состоит в том что хотелось бы заблокировать за пределами класса myclass как редактировать сам список так и поля элементов списка.
Заменить поля класса cell на свойства с приватными сеттерами, свойства задавать из конструктора. Отдавать не список, а ReadOnlyList<T>.

Про свойства вообще в любом учебнике написано. Тут не нейронку надо мучать, а просто почитать чего.
2
151 / 135 / 29
Регистрация: 02.07.2013
Сообщений: 962
25.08.2025, 09:47
Цитата Сообщение от Usaga Посмотреть сообщение
Отдавать не список, а ReadOnlyList<T>.
для UI можно и копию сделать. из соображения удобства для многопоточности. заодно и редактирование никогда ничего не испортит.
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,218
25.08.2025, 10:01
Цитата Сообщение от golosalex Посмотреть сообщение
для UI можно и копию сделать.
Ерунда. Там Ethernet фреймами фигачит, так еще и копии делать на каждую пачку что-ли?
0
151 / 135 / 29
Регистрация: 02.07.2013
Сообщений: 962
25.08.2025, 11:48
Цитата Сообщение от IamRain Посмотреть сообщение
Ерунда. Там Ethernet фреймами фигачит, так еще и копии делать на каждую пачку что-ли?
только для того что виден в UI в данный момент.
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,218
25.08.2025, 12:03
golosalex, может быть, но боюсь детали от ТС мы еще нескоро узнаем.
0
1956 / 874 / 352
Регистрация: 05.09.2021
Сообщений: 1,387
25.08.2025, 16:11
Jack0v,
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class MyClass
{
    public class Cell
    {
        public required int Number { get; init; }
        public required string Type { get; init; }
        public required bool Check { get; init; }
    }
 
    public IReadOnlyList<Cell> Cells => _cells;
 
    private readonly List<Cell> _cells = [];
 
    public void CreateList()
    {
        _cells.Add(
            new Cell
            {
                Number = 1,
                Type = "A",
                Check = false,
            }
        );
 
        _cells.Add(
            new Cell
            {
                Number = 2,
                Type = "B",
                Check = false,
            }
        );
    }
}
 
static class Program
{
    static void Main()
    {
        MyClass MyObj = new();
        MyObj.CreateList();
 
        foreach (MyClass.Cell Cell in MyObj.Cells)
        {
            Console.WriteLine($" {Cell.Number}, {Cell.Type}, {Cell.Check}");
        }
 
        MyObj.Cells.Add(new MyClass.Cell()); // CS1061
        MyObj.Cells[0].Number = 1000; // CS8852
        MyObj.Cells[0].Check = true; // CS8852
    }
0
0 / 0 / 0
Регистрация: 04.02.2025
Сообщений: 53
25.08.2025, 20:29  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Заменить поля класса cell на свойства с приватными сеттерами, свойства задавать из конструктора. Отдавать не список, а ReadOnlyList<T>.
Цитата Сообщение от anton78spb Посмотреть сообщение
Jack0v,
Да, но в этом случае теряется возможность редактировать поля элементов списка в классе myclass.

Цитата Сообщение от IamRain Посмотреть сообщение
детали от ТС
Там список готовится в течении нескольких секунд и потом передаётся в ЮИ.

Цитата Сообщение от golosalex Посмотреть сообщение
для UI можно и копию сделать
Рассматриваю и такой вариант. Если тут ничего не выйдет, то, скорее всего, так и сделаю.
0
1956 / 874 / 352
Регистрация: 05.09.2021
Сообщений: 1,387
26.08.2025, 08:50
Лучший ответ Сообщение было отмечено Jack0v как решение

Решение

Цитата Сообщение от Jack0v Посмотреть сообщение
Да, но в этом случае теряется возможность редактировать поля элементов списка в классе myclass.
Добавил возможность редактировать внутри класса, где создается список.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class MyClass
{
    public interface ICell
    {
        public int Number { get; }
        public string? Type { get; }
        public bool Check { get; }
    }
 
    public class Cell : ICell
    {
        public int Number { get; set; }
        public string? Type { get; set; }
        public bool Check { get; set; }
    }
 
    public IReadOnlyList<ICell> Cells => _cells;
 
    private readonly List<Cell> _cells = [];
 
    public void CreateList()
    {
        _cells.Add(new Cell());
        _cells.Add(new Cell());
 
        _cells[0].Number = 1;
        _cells[0].Type = "A";
        _cells[0].Check = false;
 
        _cells[1].Number = 2;
        _cells[1].Type = "B";
        _cells[1].Check = false;
    }
}
 
static class Program
{
    static void Main()
    {
        MyClass MyObj = new();
        MyObj.CreateList();
 
        foreach (var Cell in MyObj.Cells)
        {
            Console.WriteLine($" {Cell.Number}, {Cell.Type}, {Cell.Check}");
        }
 
        // MyObj.Cells.Add(new MyClass.Cell()); // CS1061
        // MyObj.Cells[0].Number = 1000; // CS0200
        // MyObj.Cells[0].Check = true; // CS0200
    }
}
Добавлено через 20 минут
Jack0v, Можно даже скрыть класс Cell.
C#
1
2
3
4
5
6
    private sealed class Cell : ICell
    {
        public int Number { get; set; }
        public string? Type { get; set; }
        public bool Check { get; set; }
    }
1
Эксперт .NET
 Аватар для Usaga
14072 / 9289 / 1347
Регистрация: 21.01.2016
Сообщений: 34,870
26.08.2025, 15:45
Цитата Сообщение от Jack0v Посмотреть сообщение
Да, но в этом случае теряется возможность редактировать поля элементов списка в классе
Вокруг myclass можно сделать readonly класс-обёртку. Но точно ли ты какой-то практический вопрос решаешь?
1
0 / 0 / 0
Регистрация: 04.02.2025
Сообщений: 53
27.08.2025, 23:37  [ТС]
Цитата Сообщение от anton78spb Посмотреть сообщение
Добавил возможность редактировать внутри класса, где создается список.
Ругается на [] в private readonly List<Cell> _cells = [];
CS1525 недопустимый термин в выражении

Цитата Сообщение от Usaga Посмотреть сообщение
Но точно ли ты какой-то практический вопрос решаешь?
Ну можно обойтись и без всего этого, но с этим будет лучше.

Добавлено через 9 минут
Цитата Сообщение от Jack0v Посмотреть сообщение
Ругается на []
Кажись разобрался, вроде как можно заменить на new List<Cell>()
0
1956 / 874 / 352
Регистрация: 05.09.2021
Сообщений: 1,387
28.08.2025, 11:55
Цитата Сообщение от Jack0v Посмотреть сообщение
Ругается на [] в private readonly List<Cell> _cells = [];
У меня .NET 8.0, соответственно C# 12. Там добавили упрощенную инициализацию коллекций. Можно пустой список / массив через = []; создавать (инициализировать).
Цитата Сообщение от Jack0v Посмотреть сообщение
Кажись разобрался, вроде как можно заменить на new List<Cell>()
Да, все верно. Именно так.
0
Эксперт .NET
 Аватар для Wolfdp
3781 / 1755 / 371
Регистрация: 15.06.2012
Сообщений: 6,516
Записей в блоге: 3
28.08.2025, 14:51
Цитата Сообщение от Usaga Посмотреть сообщение
Но точно ли ты какой-то практический вопрос решаешь?
+1

Jack0v, вы вообще какую проблему решаете?
0
0 / 0 / 0
Регистрация: 04.02.2025
Сообщений: 53
29.08.2025, 04:31  [ТС]
Цитата Сообщение от anton78spb Посмотреть сообщение
Да, все верно. Именно так.
Да проверил, всё работает.

Но в целом, всё это как-то мудрёно конечно.

Цитата Сообщение от Wolfdp Посмотреть сообщение
Jack0v, вы вообще какую проблему решаете?
Хочу для внешнего кода ограничить доступ по записи, чтобы никто своими шаловливыми ручками там ничего не попортил и потом меня не обвинял.
0
Эксперт .NET
 Аватар для Usaga
14072 / 9289 / 1347
Регистрация: 21.01.2016
Сообщений: 34,870
29.08.2025, 08:50
Цитата Сообщение от Jack0v Посмотреть сообщение
Хочу для внешнего кода ограничить доступ по записи, чтобы никто своими шаловливыми ручками там ничего не попортил и потом меня не обвинял.
Сомнительная мотивация переусложнять код...
0
0 / 0 / 0
Регистрация: 04.02.2025
Сообщений: 53
30.08.2025, 01:57  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Сомнительная мотивация переусложнять код...
Да ладно, не такое уж и сильное переусложнение.
0
Эксперт .NET
 Аватар для Usaga
14072 / 9289 / 1347
Регистрация: 21.01.2016
Сообщений: 34,870
30.08.2025, 07:11
Jack0v, да такое уж. Вместо работы над полезной функциональностью тратить время на вот это вот)
0
Эксперт .NET
 Аватар для Wolfdp
3781 / 1755 / 371
Регистрация: 15.06.2012
Сообщений: 6,516
Записей в блоге: 3
30.08.2025, 16:40
Цитата Сообщение от Jack0v Посмотреть сообщение
Да ладно, не такое уж и сильное переусложнение.
Ну, как сказать...

Если нужно закрыть внутри либы, то делаем internal и всё. Если же скрываем внутри проекта, то абсолютно любая реализация разбивается об тот факт что кодер может просто зайти в нужный файл и добавить public конструктор. Также существует рефлексия, так что особо настойчивых вы фиг остановите.

Я бы лично в первую очередь рассматривал использование маркер Obsolete, чтобы колеги просто видели "не трож", а в местах его использования налепил игнорирование.

Если очень хочеться прям "запретить", можно вместо упаковки сделать следующее:
- объявляем конструктор и сеттер как приватные
- добавляем интерфейс, который будет позволяеть для конкретного экземпляра менять значения и уметь создавать сам объект
- внутри "запрещаемого" класса делаем реализацию интерфейса
- в интересующих классах добавляем статический сеттер реализации интерфейса
- в "запрещаемом" классе в статическом конструкторе прокидываем реализацию интерфейса в интересующие классы.

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

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public class Neko
{
    public string Name { get; private set; }
 
    static Neko()
    {
        NekoManager1.NekoEditor = new NekoEditor();
        NekoManager2.NekoEditor = new NekoEditor();
    }
    private Neko(string name)
    {
        Name = name;
    }
 
    private class NekoEditor : INekoEditor
    {
        public void ChangeName(Neko neko, string name)
            => neko.Name = name;
 
        public Neko Create(string name)
            => new(name);
    }
}
 
internal interface INekoEditor
{
    public Neko Create(string name);
    public void ChangeName(Neko neko, string name);
}
 
public class NekoManager1
{
    private static INekoEditor nekoEditor = default!;
 
    internal static INekoEditor NekoEditor
    {
        set => nekoEditor = value;
    }
 
    public Neko[] InitList(int count)
    {
        var list = new Neko[count];
        for (int i = 0, number = 1; i < count; i++, number++)
            list[i] = nekoEditor.Create($"cat number {number}");
        return list;
    }
}
 
public class NekoManager2
{
    private static INekoEditor nekoEditor = default!;
 
    internal static INekoEditor NekoEditor
    {
        set => nekoEditor = value;
    }
 
    public void Shuffle(Neko[] nekos)
    {
        var random = new Random();
        random.Shuffle(nekos);
        for (int i = 0, number = 1; i < nekos.Length; i++, number++)
            nekoEditor.ChangeName(nekos[i], $"cat number {number}");
    }
}
Замечу что это один из возможных сценариев. Очень часто просто оперируют IReadOnly или что-то в таком духе, как выше указывал Usaga, . Лично я по вашему коду не совсем понял зачем что-либо вообще запрещать, там просто модели данных, причём вроде неизменяемые. Влепить тот же record и забыть как страшный сон.

Добавлено через 2 минуты

Не по теме:

Цитата Сообщение от Usaga Посмотреть сообщение
Вместо работы над полезной функциональностью тратить время на вот это вот)
Или на форум. А можно было бы качать эльфа 80lvl.... ヾ(≧▽≦*)o

0
0 / 0 / 0
Регистрация: 04.02.2025
Сообщений: 53
01.09.2025, 03:15  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Вместо работы над полезной функциональностью тратить время на вот это вот
Полезная функциональность вся сделана. Остались такие вот мелкие вопросы порешать.

Цитата Сообщение от Wolfdp Посмотреть сообщение
кодер может просто зайти в нужный файл и добавить public конструктор
Да пусть делает что хочет, такое вычислить можно на раз.
0
Эксперт .NET
 Аватар для Wolfdp
3781 / 1755 / 371
Регистрация: 15.06.2012
Сообщений: 6,516
Записей в блоге: 3
01.09.2025, 13:56
Цитата Сообщение от Jack0v Посмотреть сообщение
Да пусть делает что хочет, такое вычислить можно на раз.
дык и без этой писанины вычисляется на раз. Или вы code repository не используете?

Учитывая что вы так особо и не расписали суть задачи, пока по описанию выглядит что нужен record или его аналог. Конструктор ограничивать я тут вообще не вижу смысла. Разве что у вас одна модель на всё и вся, и public field подсказывает что где-то оно так и есть.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.09.2025, 13:56
Помогаю со студенческими работами здесь

Запрет редактирования столбца DataGrid
Добрый день всем! Весь день убил на решение такой проблемы: вставляю в DataGrid DataTable: ...

Запрет редактирования поля ComboBox
Как сделать так, чтобы нельзя самому изменять вписывать чего либо в comboBox1 ? только данные...

Запрет редактирования определенных колонок в DataGridView
Здравствуйте! Подскажите как запретить редактирование определенных колонок в DataGridView

Запрет редактирования файла
Добрый день. Программа создает некоторый файл, необходимо запретить пользователю открывать его(или...

Запрет редактирования
Здравствуйте. Имеется проблема данного характера: Есть приложение WF, компонент DataGridView(в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru