Мне кажется, полезна будет возможность использовать initializer block после любого выражения, возвращающего объект, а не только после операции new. Это особенно полезно при использовании DI-контейнеров, которые, вроде как, логически замещают new, но полного синтаксиса не предоставляют.
Например, так:
var o = container.Resolve<MyObject>()
{
Field1 = 7,
Field2 = "hello world"
};
Ц>* Сигнатурные ограничения для конструкторов обобщённых типов: не просто конструктор по умолчанию, а возможность указать желаемую сигнатуру конструктора объекта. Например, для инджектирования объекта через конструктор, а не через свойства -- раз и до конца жизни объекта.
Очень поддерживаю. Нужна возможность декларировать интерфейс создания семейства объектов.
Здравствуйте, xorets, Вы писали:
X>Очень поддерживаю. Нужна возможность декларировать интерфейс создания семейства объектов.
Это просто идея, и я не уверен в её состоятельности. Я на самом деле очень люблю неизменяемые типы, но таким образом даже от левого класса нужна поддержка такого специфического конструирования объекта, хотя это забота уже самого типа. Поведение принято решать через методы интерфейсов. Быть может, здесь лучше использовать фабрику объектов, которая знает как создать неизменяемый объект?
Здравствуйте, Аноним, Вы писали:
А>При всем моем уважении к Скиту, его идея супернавороченных enum'ов мне не нравится. Что чаще всего надо? Парсинг и прочие конвертеры привязать к enum'у, чтобы не болтались в левых классах типа Utils. То есть, если иметь возможность добавить статические методы, этого более чем достаточно. Объявлять enum каким-то class enum совсем не надо. Ну, или, если хочется иметь методы .To(), можно сделать как в мутаторах — в контексте нестатических методов enum'а считать value ключевым словом.
А>Все остальное решается через наследование. Наследуйся, там добавишь все, что надо. Примерно, как от класса с одним целочисленным полем. Соответственно, доступ к значению через то же самое base.value.
Мутно как-то. В Java, кроме того, такие перечисления можно использовать в аннотациях (аттрибутах в терминологии C#).
Здравствуйте, k0st1x, Вы писали:
K>было бы здорово иметь возможность писать
K>
K>interface IFoobar { void DoWork(); }
K>...
K>object value;
K>if(value is IFoobar) {
K> value.DoWork(); // не надо делать "cast" или "as"
K>}
K>
Уже существующим синтаксисом не обойтись, нужно новый придумывать, иначе такая фича поломает обратную совместимость.
interface IMyIntf
{
void IntfMethod();
}
class MyClass: IMyIntf
{
public void ClassMethod() {}
void IMyIntf.IntfMethod() {}
}
IMyIntf o = ...;
if (o is MyClass)
{
o.IntfMethod(); // сейчас работает, а если o скастится к MyClass, то перестанет компилиться.
}
Здравствуйте, Jack128, Вы писали:
J>Здравствуйте, k0st1x, Вы писали:
K>>было бы здорово иметь возможность писать
K>>
K>>interface IFoobar { void DoWork(); }
K>>...
K>>object value;
K>>if(value is IFoobar) {
K>> value.DoWork(); // не надо делать "cast" или "as"
K>>}
K>>
J>Уже существующим синтаксисом не обойтись, нужно новый придумывать, иначе такая фича поломает обратную совместимость.
вообще, идею увидел в проекте Kotlin.
jetbrains как-то живет с такой фичей
Re[4]: Что нужно добавить в C#?
От:
Аноним
Дата:
19.02.13 13:21
Оценка:
Здравствуйте, Цыба, Вы писали:
Ц>Здравствуйте, Аноним, Вы писали:
А>>При всем моем уважении к Скиту, его идея супернавороченных enum'ов мне не нравится. Что чаще всего надо? Парсинг и прочие конвертеры привязать к enum'у, чтобы не болтались в левых классах типа Utils. То есть, если иметь возможность добавить статические методы, этого более чем достаточно. Объявлять enum каким-то class enum совсем не надо. Ну, или, если хочется иметь методы .To(), можно сделать как в мутаторах — в контексте нестатических методов enum'а считать value ключевым словом.
А>>Все остальное решается через наследование. Наследуйся, там добавишь все, что надо. Примерно, как от класса с одним целочисленным полем. Соответственно, доступ к значению через то же самое base.value.
Ц>Мутно как-то. В Java, кроме того, такие перечисления можно использовать в аннотациях (аттрибутах в терминологии C#).
Я не понимаю, что значит "мутно".
Я исхожу из реальной проблемы: часто встречаешь набор функций, которые относятся только к enum'у, но хостятся в классе Utils, Converters и т.п. Если их можно было бы засунуть в сам enum, было бы понятно:
public enum LengthUnit
{
Millimeter = 1,
Meter = 1000,
Inch = 25400;
public static LengthUnit Parse(string text)
{
if (text == "mm") return LengthUnit.Millimeter;
if (text == "m") return LengthUnit.Meter;
if (text == "\"") return LengthUnit.Inch;
}
public string GetSystem()
{
switch (value)
{
case LengthUnit.Millimeter:
case LengthUnit.Meter:
return"Metric";
case LengthUnit.Inch:
return"US";
default: return string.Empty;
}
}
}
...
var system = LengthUnit.Parse("mm").GetSystem();
Какие проблемы у Скита решаются с помощью class enum мне понять вообще не удалось.
То есть, я боюсь, что если и сделают енамы более объектными, то вместо маленького нужного инструмента зафигачат большой и ненужный. Если кому-то нужен класс и enum в одном флаконе, пусть пишет, как в PHP, то есть, класс с константами, с методами, конструкторами и прочим. А чтобы не копипастить код, когда уже есть enum, а свой такой класс надо построить на его базе, вполне достаточно поддержать наследование. И наследование самих enum'ов, конечно. Тоже не хватает, чтобы, допустим, от enum'а с секундой унаследовать как СИ, так и грамм-секундную систему. И чтобы секунда там и там была одной и той же.
Здравствуйте, k0st1x, Вы писали:
K>Здравствуйте, Jack128, Вы писали:
J>>Здравствуйте, k0st1x, Вы писали:
K>>>было бы здорово иметь возможность писать
K>>>
K>>>interface IFoobar { void DoWork(); }
K>>>...
K>>>object value;
K>>>if(value is IFoobar) {
K>>> value.DoWork(); // не надо делать "cast" или "as"
K>>>}
K>>>
J>>Уже существующим синтаксисом не обойтись, нужно новый придумывать, иначе такая фича поломает обратную совместимость.
K>вообще, идею увидел в проекте Kotlin. K>jetbrains как-то живет с такой фичей
кстати, здесь описание этой фичи
до этой минуты даже не догадывался, что это называется "Pattern matching" )
// Тип переменной - массив, а хотелось бы иметь IList<int> или даже IReadOnlyCollection<int>.var list1 = new int[] { 0, };
// Явное указание типа переменной - выход, но смотрится не симпатично когда кругом (выше и ниже по коду) var-ы,
// а так же не возможно в выражении let внутри query
IList<int> list2 = new int[] { 0, };
// Приведение типа не выглядит как безопасная операция.
// Внимание при чтении концентрируется на типе, а не на выражении, которое важнее.var list3 = (IList<int>)new int[] { 0, };
С уточнением типов:
var list = new int[] { 0, } : IList<int>;
var predicate = item => item > 3 : Func<int, bool>; // Можно ещё и так использовать, да.
Как уже скзали, расширение query для возможности естественного вызова Aggregate/Skip/etc (например как в VB) + поддержка пользовательских расширений.
Например сейчас:
var temp =
from item in collection
where item.Some > 3
select item;
var x1 = new MyCollection<X>(temp, someAdditionalParameter: 42);
var x2 = temp.ToMyDictionary(item => item.Key, item => item.Data);
var x3 = temp.Percentile(0.95);
Хотелось бы:
// Вызов конструктораvar x1 =
from item in collection
where item.Some > 3
select item into temp as new MyCollection<X>(temp, someAdditionalParameter: 42);
// Просто вызов некоего методаvar x2 =
from item in collection
where item.Some > 3
select item into temp as MyExtensions.ToMyDictionary(temp, item => item.Key, item => item.Data);
// Вызов метода-расширенияvar x3 =
from item in collection
where item.Some > 3
select item into temp as temp.Percentile(0.95);
Тип переменной "х" — это тип выражения после "as". Так же получится удобное использование First[OrDefault] и т.п. если не придумают, как эти методы более естественно внедрить в query.
Так же реквестую nameof/infoof и "ПМ и АТД"
Синтаксис для простого написания имутабельных типов и билдеров к ним, если эту задачу нельзя не будет решить с появлением Розлина.
private delegate bool TryParse<T>(string text, out T result);
// Так можно
TryParse<int> parse1 = (string text, out int result) => Int32.TryParse(text, out result);
// А хотелось бы и так
TryParse<int> parse2 = (text, out result) => Int32.TryParse(text, out result);
Полная поддержка компилятором Expression, в ветвлениями и прочим. Поддержка в выражениях подстановок. Хотя бы так: