2012-04-28 2 views
3

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

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

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

+2

Я m довольно уверен, что это не то, что вы используете прямо сейчас, потому что ваш код не будет компилироваться. Кроме того, что-то вроде версии протокола не подходит для поля 'const', потому что оно на самом деле не является постоянным - оно может измениться в будущем. – svick

+0

@svick Ах да, мой код на самом деле не имеет набора в нем, я должен изменить это в ответе. Это была моя первая мысль, прежде чем я попытался ее скомпилировать. – cost

ответ

7

Вы можете объявить свойство с только ПОЛУЧИТЬ аксессор (даже не объявляя множество аксессора, даже не частный):

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

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

// 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, и пересобрать класс только библиотеку, без перекомпиляции программы, затем поставить новую библиотеку классов в папке с программой и выполнить его. Вы увидите:

Constant : 1 
Getter : 2 

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

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

public static readonly Int16 protocol_version = 1; 
+0

Это точка goo, но если что-то не является константой, то не делайте ее' const' в первую очередь. – svick

+0

@svick: видя, как был сформулирован вопрос («Я бы предпочел сделать это только с константой»), я подумал, что, возможно, для него это не было ясно. –

+0

Это хороший момент, я не знал, что константы работали так – cost

1

Вобще:

public const Int16 protocol_version = 1; 

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

+0

Это может показаться глупым, но когда я использую get и устанавливаю для переменных, я получаю другой значок в intellisense, чем когда у меня есть открытая публичная переменная. Все мои открытые переменные используют геттеры и сеттеры (некоторые частные), и я хотел быть последовательным, так как это библиотека – cost

+1

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

+0

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

2

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

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

public Int16 ProtocolVersion { get { return protocol_version; } } 

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

public const Int16 ProtocolVersion = 1 
+0

Я знаю, что это глупо, я просто старался соответствовать моей библиотеке – cost

+0

@cost Я действительно получаю это :) Просто сделайте общедоступные свойства и константы имеют одинаковый стиль кодирования, и intellisense будет показывать его аналогичным образом. В некоторых случаях полезно иметь возможность отличать константы от свойств, поскольку вы знаете, что константа не может измениться, но свойство readonly ничего не говорит о том, как обрабатывается базовая переменная внутри класса. – edvaldig

+1

Еще один момент: в использовании 'Int16' нет никакой пользы. Используйте 'int',' Int32' или, может быть, 'string'. –

0

константы не могут быть переназначены, следовательно, почему они называются постоянными поэтому просто сделать protocol_version public

private const Int16 protocol_version = 1; 
+1

И затем назовите его 'ProtocolVersion' –

Смежные вопросы