Существуют некоторые связанные вопросы здесь и здесь, но они действительно не дали мне удовлетворительные ответы. Проблема состоит в том, что перечисления, вложенные в классе в C#, не могут иметь того же имени как свойство класса. Мой пример:
public class Card
{
public enum Suit
{
Clubs,
Diamonds,
Spades,
Hearts
}
public enum Rank
{
Two,
Three,
...
King,
Ace
}
public Suit Suit { get; private set; }
public Rank Rank { get; private set; }
...
}
Существует несколько опций бездельничать это, но они не кажутся правильным мне.
Я мог переместить перечисления вне класса, но затем Вы просто скажете Suit
вместо Card.Suit
, который кажется неправильным мне. Что такое a Suit
вне контекста a Card
?
Я мог переместить их вне класса и изменить их на что-то как CardSuit
и CardRank
, но затем я чувствовал бы, что пеку контекстную информацию на название перечисления, когда это должно быть обработано именем пространства имен или классом.
Я мог изменить имена перечислений к Suits
и Ranks
, но это нарушает рекомендации по именованию Microsoft. И это просто не чувствует себя хорошо.
Я мог изменить имена свойства. Но к какой? Это интуитивно чувствует себя хорошо мне, чтобы хотеть сказать Suit = Card.Suit.Spades
.
Я мог переместить перечисления в отдельный статический названный класс CardInfo
содержа только эти перечисления. Если я не могу придумать ничто больше, я думаю, что это - наилучший вариант.
Таким образом, я задаюсь вопросом, что другие люди сделали в аналогичных ситуациях. Также было бы хорошо знать, почему это запрещено. Возможно, Eric Lippert или кто-то могли вмешаться на решении запретить его? На него кажется, что только создает неоднозначность в классе, и это могло быть разрешено путем принуждения использования this.Suit
для имени свойства. (Подобный устранению неоднозначности между местными жителями и участниками.) Я предполагаю, что это было не учтено из-за "каждой функции, запускает с-100 точек" вещь, но мне было бы любопытно на предмет дискуссий по поводу этого.
Также было бы неплохо узнать, почему это запрещено. Может быть, Эрик Липперт или кто-то может вмешаться в решение запретить это?
Суть правила состоит в том, чтобы гарантировать отсутствие двусмысленности внутри класса при поиске имени. Определенные области кода обозначены как определяющие «пространство объявлений». Основное правило пространств объявлений : никакие две вещи, объявленные в одном пространстве объявлений, не имеют одинакового имени (за исключением методов, которые должны отличаться подписью , а не именем ].)
Исключения из этого правила только сбивают с толку, а не меньше. Я согласен с тем, что досадно, что у вас не может быть свойства и перечисления с тем же именем, объявленных в одном и том же пространстве объявлений, но как только вы начнете делать исключения, это просто станет беспорядком. Обычно приятным свойством является то, что имя однозначно идентифицирует группу методов, параметр типа, свойство и т. Д.
Обратите внимание, что это правило применяется к вещам , объявленным в пространстве объявлений, а не к вещам , используемым в пространстве объявлений. Совершенно законно сказать «public Suit Suit {get; set;}» при условии, что тип Suit не объявлен в том же пространстве декларации, что и свойство. Когда кто-то говорит «Suit.X», выяснить, относится ли X к типу (то есть X является статическим членом) или свойству (то есть X является членом экземпляра), немного сложно. Подробности см. В моей статье о том, как мы это делаем:
http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx
Я бы переместил перечисления за пределы определения класса и использовал пространство имен, чтобы указать, что они относятся к картам. Я вообще не люблю перечисления, вложенные в классы. Вы правы насчет множественности, хотя: единственное число для обычных перечислений, множественное - для перечислений флагов.
-121--1393988-можно использовать функцию Thread.Sleep ()
Thread.sleep(4000);
myfunction();
Ваша функция будет выполняться через 4 секунды. Однако это может приостановить всю программу...
-121--2020330-Перечисления в основном представляют собой определенные типы данных. Вы не будете использовать «int» или «string» в качестве имени члена, поэтому я думаю, что не менее плохая идея использовать имена перечисления и имена членов в вашем случае.
Я предпочитаю именовать перечисления с помощью существительного, за которым следуют Параметры. В вашем случае:
SuitOptions
RankOptions
Ведь перечисление - это всего лишь набор возможных вариантов, верно?
У вас тогда будет:
myCard.Suit = Card.SuitOptions.Clubs;
Что, на мой взгляд, имеет смысл и вы все еще можете знать при просмотре текста, является ли тогда перечислением или свойством.
-121--1393986-Может быть:
case "$DIVIDER" in
(*\\*) DIVIDER=$(echo "$DIVIDER" | sed 's/\\/\\\\/g');;
esac
Я играл с этим сценарием:
for DIVIDER in 'xx\n' 'xxx\\ddd' "xxx"
do
echo "In: <<$DIVIDER>>"
case "$DIVIDER" in (*\\*) DIVIDER=$(echo "$DIVIDER" | sed 's/\\/\\\\/g');;
esac
echo "Out: <<$DIVIDER>>"
done
Run with 'ksh' или 'bash' (но не 'sh') на MacOS X:
In: <<xx\n>>
Out: <<xx\\n>>
In: <<xxx\\ddd>>
Out: <<xxx\\\\ddd>>
In: <<xxx>>
Out: <<xxx>>
-121--4817541- Я бы переместил перечисления за пределы определения класса и использовал пространство имен, чтобы указать, что они связаны Я вообще не люблю перечисления, вложенные в классы. Вы правы насчет множественности, хотя: единственное число для обычных перечислений, множественное - для перечислений флагов.
Я предпочитаю называть перечисления, используя существительное, за которым следует Параметры. В вашем случае:
SuitOptions
RankOptions
В конце концов, перечисление - это всего лишь набор возможных параметров, не так ли?
Тогда у вас будет:
myCard.Suit = Card.SuitOptions.Clubs;
Что, на мой взгляд, имеет смысл, и при просмотре текста вы все еще можете узнать, является ли это перечислением или свойством.
Я бы согласился переместить определение перечисления в отдельное место. В настоящее время перечисления видны только через карточку, поэтому, если вы хотите проверить туза, вам нужно будет сделать
if (card.CardSuit == Card.Suit.Ace) { } //need different name for Suit field
Где, если вы переместили его в отдельное определение, вы могли бы сделать это, если сделаете его глобальным:
if (card.Suit == Suit.Ace) { } //no naming clashes, easier to read