Этот дизайн хорошо в C#
Просто интересно, является ли это "хорошей практикой" или нет. Я хочу создать класс токенов, который может содержать строку или целое число и обрабатывать токены любого типа. Я посмотрел на открытые дженерики, дженерики, рефераты, переопределения и т. д. и выбрал простое решение ниже:-
using System.IO; using System; public class Token { public dynamic Value {get; set;} } class Program { static void Main() { Token token1; Token token2; token1 = new Token(); token2 = new Token(); token1.Value=1; token2.Value="hi"; Console.WriteLine(token1.Value); Console.WriteLine(token2.Value); token1.Value=token2.Value; Console.WriteLine(token1.Value); Console.WriteLine(token2.Value); } }
Что я уже пробовал:
?? как и выше - не знаете, что сюда положить ?
F-ES Sitecore
Вероятно, вам лучше пойти по пути дженериков. Редко бывает так, что вы никогда по-настоящему не заботитесь о рассматриваемом типе, и если все, что вы делаете, это печатаете значение в консоль или журнал и т. д., то у вас может быть базовый универсальный класс и классы concerete, которые наследуют этот базовый класс и предоставляют свои собственные реализации ToString
абстрактный класс MyBaseClass< t>
{
public T Value {get; set;}
абстрактная строка ToString();
}
класс IntClass : MyBaseClass< int>
{
public string ToString()
{
значение.Метод toString();
}
}
Это позволяет вам использовать любой тип, и каждый конкретный класс может затем предоставить свою собственную реализацию ToString, поскольку вы можете захотеть, чтобы "T" был классом типа Person со сложными свойствами.
ninjaef
Мне это нравится. Он также согласуется с базовыми / простыми типами (int, int32,...), не уверен, как вы их называете. Спасибо. Но как мне объявить объект MyBaseClass и вызвать его?Ценность для обоих?
ninjaef
хорошо, но как мне объявить объект для получения токена:
Токен MyBaseClass; //не будет компилироваться?
...
...
token = getNextToken () / / может возвращать строку или int
если<<токен является int>, то ... еще &ЛТ;&ЛТ;маркер строки&ГТ;&ГТ; ...
???
F-ES Sitecore
Вам придется работать с конкретным производным конкретным типом или MyBaseClass< int>, например. Или пусть класс, который должен использовать getNextToken, также будет универсальным классом. Нет никакого реального способа обработки полностью типо-агностических данных, вы должны указать тип в какой-то момент, или getNextToken возвращает фиксированный тип, такой как строка или объект, но опять же вызывающий код должен знать, к какому типу привести. Вы должны подумать о проблеме, которую вы на самом деле пытаетесь решить, .net-это скомпилированный язык, поэтому на самом деле у него нет понятия неопределенных типов.
ninjaef
оригинал ...
токен публичного класса
{
public dynamic Value {get; set;} / / компилируется
}
Токен mytoken = GetNextToken () / / работает во время выполнения; токен.Значение может дать (int) или (char) и т. д.
если mytoken.Тип = число тогда &ЛТ;&ЛТ;лечить как int&ГТ;> еще &ЛТ;&ЛТ;лечить как char&ГТ;&ГТ;
/- значит, полиморфизм?
...
как я уже сказал, Все работает так, как требуется, возможно, проще, чем ваше решение, но мне было интересно, является ли мое решение хорошей практикой - очевидно, оно разрешено в C# и компилируется/запускается
??
F-ES Sitecore
Лично я бы сказал, что это не очень хороший дизайн, чтобы использовать динамический. Вы все еще не объяснили свое окончательное намерение, поэтому трудно дать конкретный совет. Единственное, что вы действительно можете сделать с чем-то, тип которого вы никогда не знаете, - это преобразовать его в строку, так что вы можете также использовать строку в качестве своего токена и получить код, который создает токен для преобразования токена в строку.
ninjaef
довольно самоочевидно, как и выше, я пишу парсер, и это включает в себя токенизатор. каждый токен считывается (getnexttoken) , где тип (int, char, string, other) определяется во время выполнения, поскольку определение токена представляет собой текстовый файл с регулярными выражениями, т. е.
Альфа=[a-z|A-Z]
Цифра=[0-9]
ЦЕЛОЕ ЧИСЛО = ЦИФРА+
ИДЕНТИФИКАТОР = АЛЬФА (АЛЬФА | ЦИФРА)+
и т.д.
таким образом, во время выполнения тип токена определяется грамматикой
поэтому я хочу иметь возможность определить "универсальный" класс, в котором значение может быть интерпретировано во время выполнения. динамический вид моделей нетипизированные языки, такие как python и т. д.
не так хорошо, как вы говорите, в C#, я согласен, но компилятор позволяет вам это делать, а CLR позволяет вам это запускать!
?
F-ES Sitecore
В этой ситуации вы могли бы посмотреть на фабричный шаблон, который проанализировал бы токен и вернул бы класс правильного типа для этого токена. Опять же, все сводится к тому, как вы на самом деле используете токен.
ninjaef
интересно, не могли бы вы объяснить / пример, пожалуйста?
EDIT: токены потребляются как символы, в соответствии с грамматикой, описанной выше, а затем преобразуются в int, если они ЦЕЛОЧИСЛЕННЫ (в соответствии с приведенным выше кодом)и т. д.
F-ES Sitecore
https://www.dotnetperls.com/factory
Для вас Фабрика.Get возьмет токен и в зависимости от его типа вернет конкретный конкретный класс для токена.
ninjaef
ах, прекрасно! и лучшее решение, чем мое, поскольку вы используете типобезопасную логику времени компиляции. БОЛЬШОЕ СПАСИБО!
ninjaef
а, погоди
на самом деле
это не то, что мне нужно.
в вашем примере, название опоры, я woould, чтобы цена и реквизит, который либо возвращает строку по идентификатору маркера, или int для целых маркер
не совсем то же самое, что в Примере
и
исходя из языка Си, я не знаю, как это сделать
F-ES Sitecore
Как я уже говорил, и вы не ответили, решение будет зависеть от того, что читает значение, то есть от того, что вы в конечном итоге с ним сделаете. Если все, что происходит, это то, что она записывается в журнал или на экран, то просто используйте строку, если вы делаете с ней что-то разумное, то я не вижу, как вы можете сделать что-то ценное с чем-то, тип которого вы не знаете.
ninjaef
вот оно!
терфейс к настоящему времени:
iproperty публичного интерфейса
{
public String Name { get; }
}
public class Property< t>: IProperty
{
публичное свойство(имя строки, значение T)
{
Имя name;
Value = значение;
}
public String Name { get; private set; }
public T Value { get; private set; }
public override String ToString()
{
возвращенная строка.Формат("{0}: {1}", Имя, Значение)
}
}
...
var intProp = новое свойство< int> ("Возраст", 32);
var strProp = new Property & lt;string> ("name", " Earl");
var enumProp = новое свойство<colorenum & gt; ("цвет глаз", ColorEnum.Пурпурный);
но я действительно не понимаю, что происходит, несмотря на то, что читаю msdn и онлайн
F-ES Sitecore
Когда вы определяете класс;
var intProp = новое свойство<int>();
тогда все, что вы помещаете в угловые браксеты (int в приведенном выше примере), - это то, чем становится "T", так что ваши свойства интерфейса действительно
public String Name { get; private set; }
public int Value { get; private set; }
таким образом, intProp.Value-это int, но strProp.Value-это строка, и вы решаете, каким типом станет "T", когда вы объявите\создадите класс. Однако следует отметить, что элемент "var" не должен вводить вас в заблуждение. var - это не общая переменная, которая может содержать что угодно, это просто "макрос", где var заменяется соответствующим типом вашим компилятором, так что ваш код действительно
Собственность и Л;int&ГТ; intProp = новое свойство И Л;int&ГТ;();
Собственность на<строка> У strProp = новостройку на<строка&ГТ;();
другими словами, intProp и strProp не взаимозаменяемы и не могут быть динамически распределены во время выполнения, вам все равно нужно знать, какого типа они должны быть.