Подтвердить что ты не робот

Присвоение значения унаследованному полю readonly?

Итак, у меня есть базовый класс, у которого много детей. Этот базовый класс определяет некоторые свойства и переменные readonly, которые имеют значения по умолчанию. Они могут быть разными, в зависимости от ребенка.

Readonly свойства/поля позволяют изменять значение переменной внутри конструктора, а также определение, но нигде больше. Я получаю "переменная readonly может быть назначена только в ошибке конструктора", если я попытаюсь изменить значение унаследованной переменной readonly в конструкторе дочернего класса. Почему это и как я могу обойти это без Reflection?

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

4b9b3361

Ответ 1

У Адама есть правильный ответ. Если вы беспокоитесь о пространстве, которое это займет (количество параметров в конструкторе?), Тогда вы должны решить это как другую проблему с другим решением: создать класс BaseConfig, содержащий все эти свойства, и это все, что должен быть передан. База может затем либо назначить все поля только для чтения из свойств BaseConfig, либо вместо этого вы можете удерживать Base только одно поле только для чтения типа BaseConfig и ссылаться на значение для значений.

Как это понимать, см. порядок выполнения конструктора С# относительно того, когда будут инициализированы/инициализированы поля инициализации/инициализации каждого поля класса read.

Ответ 2

Причина в том, что вы можете назначать только поля readonly в конструкторе этого класса.
Согласно определение readonly в С# Reference (выделено мной):

Если объявление поля содержит модификатор readonly, назначения поля, введенные объявлением, могут выполняться только как часть объявления или в конструкторе в том же классе.

Чтобы обойти это, вы можете создать защищенный конструктор в базе, который принимает параметр для свойства readonly.

Пример:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Base b = new Child();
            Console.WriteLine(b.i);
            Console.Read();
        }
    }

    class Base
    {
        public readonly int i;

        public Base()
        {
            i = 42;
        }

        protected Base(int newI)
        {
            i = newI;
        }
    }

    class Child : Base
    {
        public Child()
            : base(43)
        {}
    }
}

Ответ 3

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

public class BSE
{
    virtual public int Prop 
    {
        get
        {
            return 6;
         }
     }
}
public class Derived : BSE
{
    public override int Prop
    {
         get
         {
             return 10;
         }
    }
 }

Поля выходят за пределы модели наследования и перегрузки и не должны использоваться для предоставления полиморфных функций.

Ответ 4

Вы можете использовать свойство с общедоступным доступом и защищенным набором доступа. Производные классы могут установить значение этого свойства.

Ответ 5

это невозможно по дизайну. попробуйте передать значения конструктору базового класса protected