Вопрос по c# – Можно ли получить геттер для const?

4

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

<code> private const Int16 protocol_version = 1;
 public Int16 ProtocolVersion { get { return protocol_version; } }
</code>

Но я бы предпочел сделать это только с помощью const, если есть способ.

Я уверен, что это не то, что вы используете сейчас, потому что ваш код не скомпилируется. Кроме того, что-то вроде версии протокола не подходит дляconst поле, потому что оно на самом деле не является константой & # x2013; это может измениться в будущем. svick
@svick Ах, да, в моем коде нет набора, я должен изменить это в ответе. Это была моя первая мысль, прежде чем я попытался скомпилировать cost

Ваш Ответ

4   ответа
9

Вы можете объявить свойство только с помощью метода доступа get (даже не объявляя установленный метод доступа, даже не private):

private const Int16 protocol_version = 1;
public Int16 ProtocolVersion { 
    get { return protocol_version; } 
}

Это не то же самое, что определение только константы: константа будет разрешена во время компиляции, поэтому, если вы обновите библиотеку, не перекомпилировав зависимую программу, программа все равно увидит & quot; старый & quot; значение. Рассмотрим этот пример:

// The class library
using System;

namespace MyClassLibrary {
    public class X {
        public const Int16 protocol_version = 1;
        public Int16 ProtocolVersion { get { return protocol_version; } }
    }
}

// The program
using System;
using MyClassLibrary;

class Program {
    static void Main(string[] args) {
        X x = new X();
        Console.WriteLine("Constant : {0}", X.protocol_version);
        Console.WriteLine("Getter: {0}", x.ProtocolVersion);
    }
}

Теперь скомпилируйте первый раз и запустите программу. Ты увидишь

Constant : 1
Getter : 1

Затем измените protocol_version до 2 и перекомпилируйтеthe class library only, without recompiling the program, затем поместите новую библиотеку классов в папку программы и выполните ее. Ты увидишь:

Constant : 1
Getter : 2

Дело в том, что если это просто константа, значение заменяетсяat compile time.

Я думаю, что вы на самом деле ищетеstatic readonly переменная: таким образом вы избежите замены const во время компиляции, и переменная не будет изменяемой после инициализации:

public static readonly Int16 protocol_version = 1;
@cost: тогда вы могли бы использоватьstatic readonly переменная вместоconst, При этом вы избежите проблем с константностью, и переменная не будет изменяемой после инициализации.
@svick: видя, как вопрос был сформулирован («я предпочел бы сделать это только с помощью const»), я подумал, что, возможно, это различие ему не ясно.
Это точка зрения, но если что-то не является константой, то не делайте этоconst поле в первую очередь.
Это хороший момент, я не знал, что константы работают так cost
Но разве это не означает, что геттер - хорошая идея здесь? Это позволяет избежать проблемы, связанной с тем, что программа думает, что использует более старый протокол, если библиотека фактически обновлена. Хотя, как указал svick, я мог бы так же легко использовать непостоянную переменную. Я действительно использовал const только как напоминание самому себе, что оно никогда не должно изменяться программно cost
2

Вы должны иметь в виду причину существования геттеров / сеттеров. Он предназначен для управления доступом к инкапсулированной переменной, в частности, для контроля того, как переменная изменяется и кто может ее изменить. Поскольку const устанавливается только один раз и остается доступным только для чтения во время выполнения, нет причин создавать для него свойство. Установка константы public полностью допустима, поскольку она не является закрытой переменной, которую нужно защищать.

Если вы действительно ... действительно хотите сделать его свойством, просто определите его как свойство только для чтения, полностью пропустив установку:

public Int16 ProtocolVersion { get { return protocol_version; } }

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

public const Int16 ProtocolVersion = 1
Еще один момент: нет пользы в использованииInt16 , использованиеint, Int32 или, может бытьstring.
@HenkHolterman Я использую Int16, потому что единственное использование номера версии - отправка через сокет как часть рукопожатия. Я не видел необходимости отправлять 4 байта, когда 2 будет гораздо более чем достаточно cost
@cost, я действительно это понимаю :) Просто сделайте открытые свойства и константы одинаковыми по стилю кодирования, и intellisense покажет это аналогичным образом. В некоторых случаях действительно полезно иметь возможность различать константы для свойств, потому что вы знаете, что константа не может измениться, но свойство только для чтения ничего не говорит вам о том, как обрабатывается базовая переменная внутри класса.
Я знаю, что это глупо, я просто пытался соответствовать своей библиотеке cost
Я согласен с @HenkHolterman, придерживайтесь базовых типов
1

Просто делать:

public const Int16 protocol_version = 1;

Это обеспечит общественный добытчик какconst не может иметь сеттера.

Это может звучать глупо, но когда я использую get и set для переменных, в intellisense я получаю другой значок, чем когда у меня есть открытая переменная. Все другие мои открытые переменные используют геттеры и сеттеры (некоторые частные), и я хотел быть последовательным, поскольку это библиотека cost
Это не то же самое, что свойство с геттером: если вы обновите библиотеку, вам также придется перекомпилировать программу.
@PaoloTedesco Зачем вам нужно перекомпилировать программу? Единственная причина, по которой программист может просматривать номер версии, заключается в том, что библиотека, которая использует это как часть оболочки сокета, откажется общаться с другим экземпляром библиотеки, где протокол может быть старым / новым. Вместо того чтобы просто сказать «они не совпадают, слишком плохо» Я хотел, чтобы программист мог получить версию, даже если он действительно ничего не может с ней сделать. Я пытался не быть загадочным. cost
0

поэтому их называют константами, поэтому просто сделайте protocol_versionpublic

private const Int16 protocol_version = 1;
А потом позвониProtocolVersion

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