Почему статические индексаторы запрещены в C #? Я не вижу причин, по которым их нельзя допускать, а кроме того, они могут быть очень полезными.
Например:
public static class ConfigurationManager
{
public object this[string name]
{
get => ConfigurationManager.getProperty(name);
set => ConfigurationManager.editProperty(name, value);
}
/// <summary>
/// This will write the value to the property. Will overwrite if the property is already there
/// </summary>
/// <param name="name">Name of the property</param>
/// <param name="value">Value to be wrote (calls ToString)</param>
public static void editProperty(string name, object value)
{
var ds = new DataSet();
var configFile = new FileStream("./config.xml", FileMode.OpenOrCreate);
ds.ReadXml(configFile);
if (ds.Tables["config"] == null)
ds.Tables.Add("config");
var config = ds.Tables["config"];
if (config.Rows[0] == null)
config.Rows.Add(config.NewRow());
if (config.Columns[name] == null)
config.Columns.Add(name);
config.Rows[0][name] = value.ToString();
ds.WriteXml(configFile);
configFile.Close();
}
public static void addProperty(string name, object value) =>
ConfigurationManager.editProperty(name, value);
public static object getProperty(string name)
{
var ds = new DataSet();
var configFile = new FileStream("./config.xml", FileMode.OpenOrCreate);
ds.ReadXml(configFile);
configFile.Close();
if (ds.Tables["config"] == null) return null;
var config = ds.Tables["config"];
if (config.Rows[0] == null) return null;
if (config.Columns[name] == null) return null;
return config.Rows[0][name];
}
}
Приведенный выше код значительно выиграет от статического индексатора. Однако он не будет компилироваться, потому что использование статических индексаторов запрещено. Почему это так?
foreach (var enum in Enum)
:)Ответы:
Обозначение индексатора требует ссылки на
this
. Поскольку статические методы не имеют ссылки на какой-либо конкретный экземпляр класса, вы не можете использоватьthis
их с ними, и, следовательно, вы не можете использовать нотацию индексатора для статических методов.Решение вашей проблемы заключается в использовании одноэлементного шаблона следующим образом:
Теперь вы можете вызывать,
Utilities.ConfigurationManager["someKey"]
используя нотацию индексатора.источник
this
в индексаторе не обязательно, скорее всего, оно было выбрано над другими ключевыми словами, поскольку имело наибольший смысл. Для статической реализации, следующий синтаксис может быть вполне жизнеспособным:public object static[string value]
. Нет необходимости использовать ключевое словоthis
в статическом контексте.Я считаю, что это не считалось очень полезным. Я тоже думаю, что это позор - пример, который я обычно использую, - это кодирование, где
Encoding.GetEncoding("foo")
могло бы бытьEncoding["Foo"]
. Я не думаю, что это будет происходить очень часто, но, помимо всего прочего, просто кажется немного непоследовательным быть недоступным.Мне нужно было бы проверить, но я подозреваю, что он уже доступен на IL (промежуточном языке).
источник
instance
кstatic
в IL для метода собственности и газопоглощающего по результатам свойства по умолчанию в ILASM жалуясьsyntax error at token 'static'
; Я не очень хорош во вмешательстве в дела IL, но это звучит как минимум для начала.В качестве обходного пути вы можете определить индексатор экземпляра для одноэлементного / статического объекта (скажем, что ConfigurationManager является одноэлементным, а не статическим классом):
источник
Мне также был нужен (ну, скорее, хороший) статический индексатор для хранения атрибутов, поэтому я нашел несколько неудобный обходной путь:
Внутри класса, который вы хотите иметь статический индексатор (здесь: Элемент), создайте подкласс с тем же именем + «Dict». Дайте ему статический объект только для чтения в качестве экземпляра указанного подкласса, а затем добавьте желаемый индексатор.
Наконец, добавьте класс как статический импорт (следовательно, подкласс будет отображать только статическое поле).
а затем вы можете использовать его либо с заглавной буквы как Type, либо без словаря:
Но, увы, если бы кто-то действительно использовал объект как "значение" -типа, то приведенный ниже был бы еще короче (по крайней мере, как объявление), а также обеспечивал бы немедленное приведение типов:
источник
С новыми конструкциями в C # 6 вы можете упростить одноэлементный шаблон с помощью тела выражения свойства. Например, я использовал следующий ярлык, который отлично работает с code-lense:
У него есть дополнительное преимущество, заключающееся в возможности поиска и замены для обновления старого кода и унификации доступа к настройкам вашего приложения.
источник
Ключевое слово this относится к текущему экземпляру класса. Статические функции-члены не имеют указателя this. Ключевое слово this можно использовать для доступа к членам из конструкторов, методов экземпляра и средств доступа к экземпляру. (Получено из msdn ). Поскольку this ссылается на экземпляр класса, он конфликтует с природой static, поскольку static не связан с экземпляром класса.
Одним из способов решения этой проблемы может быть следующее, которое позволяет вам использовать индексатор против частного словаря, поэтому вам нужно только создать новый экземпляр и получить доступ к статической части.
Это позволяет вам полностью пропустить доступ к члену класса и просто создать его экземпляр и проиндексировать его.
источник
new ()
могли быть использованы для имени квалификатора синглтона вместо этого вроде.Current
this
словом « что-то, что использует ключевое слово», а во-вторых,this
в синтаксисеpublic string this[int index]
, строго говоря, даже не используетсяthis
указатель (как это может происходить в теле методов экземпляра) , но это просто еще одно использование токенаthis
. Синтаксисpublic static string this[int index]
может показаться несколько нелогичным, но все равно однозначным.public static string class[int index]
.Причина в том, что довольно сложно понять, что именно вы индексируете с помощью статического индексатора.
Вы говорите, что статический индексатор принесет пользу коду, но так ли это на самом деле? Все, что он сделает, это изменит это:
В это:
что никак не улучшает код; он не меньше на много строк кода, его не легче писать благодаря автозаполнению и он менее ясен, поскольку скрывает тот факт, что вы получаете и устанавливаете то, что вы называете `` Свойством '', и фактически заставляет читателя прочтите документацию о том, что именно индексатор возвращает или устанавливает, потому что никоим образом не очевидно, что это свойство, для которого вы индексируете, в то время как с обоими:
Вы можете прочитать это вслух и сразу понять, что делает код.
Помните, что мы хотим писать простой (= быстрый) код для понимания, а не код, который быстро пишется. Не путайте скорость, с которой вы можете написать код, со скоростью, с которой вы завершаете проекты.
источник