Здравствуйте, Кирилл Осенков, Вы писали:
КО>Мы в Beta 2 добавили новую фичу в язык: теперь можно вызывать свойства с параметрами при помощи синтаксиса индексеров:
Возникает резонный вопрос.
А почему бы не добавить полноценную поддержку?
Здравствуйте, Кирилл Осенков, Вы писали:
КО>Мы в Beta 2 добавили новую фичу в язык: теперь можно вызывать свойства с параметрами при помощи синтаксиса индексеров:
Это [сабж] был большущий такой облом :о))
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Мишень-сан, Вы писали:
МС>Имелось ввиду добавление возможности не только вызова, но и объявления собственных индексных свойств.
Прошу прощения, что по-аглицки:
Why not allow declaring indexed properties in C#?
A common question that we expect we’ll be getting is “why just consume? why not allow to declare such properties in C#?”. Well, the answer is not even that we first have to cost, design, spec, prototype, implement and test this feature, but rather that we think that declaring a type with an indexer is a preferred approach. It’s useful to separate the responsibilities:
The property is there to get an object. The property belongs to the parent object.
The indexer is there on the returned object to enumerate it. The indexer belongs to the returned object.
We shouldn’t be mixing these together.
Как-то пропустил этот кусочек сначала.
Хотя в том же VB.NET индексные свойства не мешают.
ИМХО, иногда проще был бы именованный индексер, чем плодить лишние классы.
Здравствуйте, Кирилл Осенков, Вы писали:
КО>Мы в Beta 2 добавили новую фичу в язык: теперь можно вызывать свойства с параметрами при помощи синтаксиса индексеров:
КО>
КО>// до
КО>excel.get_Range("A1").set_Value(Type.Missing, "ID");
КО>// после
КО>excel.Range["A1"].Value = "ID";
КО>
А если excel будет иметь тип dynamic, это будет работать?
Здравствуйте, Qbit86, Вы писали:
Q>Здравствуйте, Кирилл Осенков, Вы писали:
КО>>Мы в Beta 2 добавили новую фичу в язык...
Q>Зачем?
Поддерживаю. Действительно, зачем? Раньше как-то обходился. То, что некоторые удобства есть я не спорю, но теперь будут возникать путаницы — в каком классе реализован индексатор:
class MyRange
{
public int this[int index]
{
get {return 0;}
}
}
class Excel
{
public MyRange MyRange {get;set;}
public int Range[int index] //типа новая фича
}
........
Excel excel = CreateExcel(...);
int a = excel.Range[13];
int b = excel.MyRange[13];
ЗЫ: я так понял, что это лишь фича языка C#, а реализуется все теми же индексаторами (или свойствами с параметрами, как они еще описаны у Рихтера).
Здравствуйте, Pro100Oleh, Вы писали:
Q>>Зачем?
PO>Поддерживаю. Действительно, зачем? Раньше как-то обходился. То, что некоторые удобства есть я не спорю, но теперь будут возникать путаницы — в каком классе реализован индексатор:
Т.к. поскипанный код нельзя объявить в шарпе, то и путаницы никакой не должно быть.
Здравствуйте, Oksana Gimmel, Вы писали:
КО>>Мы в Beta 2 добавили новую фичу в язык: теперь можно вызывать свойства с параметрами при помощи синтаксиса индексеров:
КО>>// до
КО>>excel.get_Range("A1").set_Value(Type.Missing, "ID");
КО>>// после
КО>>excel.Range["A1"].Value = "ID";
OG>А если excel будет иметь тип dynamic, это будет работать?
Работает:
var app = new Microsoft.Office.Interop.Excel.Application();
dynamic book = app.Workbooks.Add();
dynamic sheet = book.Worksheets.Add();
sheet.Range["A2"] = "Test!";
book.SaveAs(@"C:\Temp\Test2.xls");
book.Close();
app.Quit();
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, Pro100Oleh, Вы писали:
Q>>>Зачем?
PO>>Поддерживаю. Действительно, зачем? Раньше как-то обходился. То, что некоторые удобства есть я не спорю, но теперь будут возникать путаницы — в каком классе реализован индексатор:
L>Т.к. поскипанный код нельзя объявить в шарпе, то и путаницы никакой не должно быть.
Путаница возникает при использовании (вторая часть приведенного мною кода), а не при обявлении кода. А объявить можно и не в шарпе.
КО>A common question that we expect we’ll be getting is “why just consume? why not allow to declare such properties in C#?”. Well, the answer is not even that we first have to cost, design, spec, prototype, implement and test this feature, but rather that we think that declaring a type with an indexer is a preferred approach. It’s useful to separate the responsibilities:
КО>
The property is there to get an object. The property belongs to the parent object.
КО> The indexer is there on the returned object to enumerate it. The indexer belongs to the returned object.
КО>We shouldn’t be mixing these together.
Тогда возникает другой вопрос: а зачем было в Бейсике это вводить? Почему там не нужно "separate the responsibilities", а в C# нужно?
Здравствуйте, gecko, Вы писали:
G>Тогда возникает другой вопрос: а зачем было в Бейсике это вводить? Почему там не нужно "separate the responsibilities", а в C# нужно?
Ну наверное уж для COM, зачем же ещё.
С появления dynamic и "улучшенной поддержки COM в C# 4.0" оное и в C# стало иметь смысл.
Я думаю вопрос должен быть такой: зачем было в VB.NET вводить возможность самому определять такие свойства?
Здравствуйте, gecko, Вы писали:
G>Тогда возникает другой вопрос: а зачем было в Бейсике это вводить? Почему там не нужно "separate the responsibilities", а в C# нужно?
Здравствуйте, Пельмешко, Вы писали:
П>Я думаю вопрос должен быть такой: зачем было в VB.NET вводить возможность самому определять такие свойства?
А что, больше к дизайну VB как к языку претензий нет?
По историческим причинам. Если бы ВБ с нуля дизайнили, то там вместо default properties и indexed properties тоже бы indexers и implicit conversion были бы.
Здравствуйте, Кирилл Осенков, Вы писали:
КО>А что, больше к дизайну VB как к языку претензий нет?
Это всё фигня по сравнению с разгильдяйством F# в плане свойств:
namespace FooBar
[<System.Reflection.DefaultMemberAttribute("DefaultIndexer")>]
type Foo =
new(value : int) = { x = value }
val mutable x : int
member this.Magic (* different accessor types *)with get () : int = this.x
and set (s : string) = printfn "%s" s
member this.DefaultIndexer
with get (index : int) = this.x
and set (index : int) (x : int) = ()
member this.NamedIndexer
with get (index : int) = this.x
and set (index : int) (x : int) = ()
C# одуревает от таких свойств, R# не может заменить var на явную аннотацию типа
var x = foo.Magic;
// Property, indexer, or event 'Magic' is not supported by the language;
// try directly calling accessor methods 'FooBar.Foo.get_Magic()' or 'FooBar.Foo.set_Magic(string)'
Вдруг type inference обманет и потом из C# юзать так придётся:
int x = foo.get_Magic();
foo.set_Magic("sdsd");
Ума не приложу почему не проверяется идентичность типов акцессоров