Здравствуйте, dotneter, Вы писали:
D>На этапе компиляции проверить равенство количества вызовов Open и Close. D>via reddit
Как-то так (студии под рукой нет)
public static ICloseable<T> Open<T>(this T value) {}
public static T Close<T>(this ICloseable<T> value) {}
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, dotneter, Вы писали:
D>>На этапе компиляции проверить равенство количества вызовов Open и Close. D>>via reddit S>Как-то так (студии под рукой нет) S>
S>public static ICloseable<T> Open<T>(this T value) {}
S>public static T Close<T>(this ICloseable<T> value) {}
S>
D>>На этапе компиляции проверить равенство количества вызовов Open и Close. D>>via reddit
П>А слева от x ну вот совсем ничего нету (например, присвоения) или я зря голову уже час ломаю?
В смысле A y = x? Пусть будет если нужно, но вообще не обязательно.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, dotneter, Вы писали:
D>>На этапе компиляции проверить равенство количества вызовов Open и Close. D>>via reddit S>Как-то так (студии под рукой нет) S>
S>public static ICloseable<T> Open<T>(this T value) {}
S>public static T Close<T>(this ICloseable<T> value) {}
S>
S>?
а можно на пальцах, как это защитит от open без close ?
Здравствуйте, Пельмешко, Вы писали:
П>Здравствуйте, dotneter, Вы писали:
D>>но вообще не обязательно.
П>ёпрст, тогда ты взорвал моё мозг!
Вообще, суть в балансировке, как она будет достигнута не столь важно.
Здравствуйте, dotneter, Вы писали:
D>Здравствуйте, Пельмешко, Вы писали:
П>>Здравствуйте, dotneter, Вы писали:
D>>>но вообще не обязательно.
П>>ёпрст, тогда ты взорвал моё мозг! D>Вообще, суть в балансировке, как она будет достигнута не столь важно.
Здравствуйте, Пельмешко, Вы писали:
П>Здравствуйте, dotneter, Вы писали:
D>>Здравствуйте, Пельмешко, Вы писали:
П>>>Здравствуйте, dotneter, Вы писали:
D>>>>но вообще не обязательно.
П>>>ёпрст, тогда ты взорвал моё мозг! D>>Вообще, суть в балансировке, как она будет достигнута не столь важно.
П>Я и не могу достигнуть балансировку в случае: П>
П>x.Open();
П>
без присваивания.
Покажите вариант с присваиванием.
Здравствуйте, dotneter, Вы писали:
D>Покажите вариант с присваиванием.
Как-то вот так:
static class Program
{
public static void Main()
{
Bar list = new Bar()
.Open()
.Open()
.Close()
.Open()
.Close()
.Close();
}
}
class Foo { }
class Foo<_> : Foo where _ : Foo { }
class Bar : Foo<Foo> { }
static class Extensions {
public static _ Close<_>(this Foo<_> x) where _ : Foo { return default(_); }
public static Foo<_> Open<_>(this _ x) where _ : Foo { return null; }
}
Здравствуйте, Пельмешко, Вы писали:
П>Здравствуйте, dotneter, Вы писали:
D>>Покажите вариант с присваиванием.
П>Как-то вот так: П>[c#] П> Bar list = new Bar() П> .Open() П> .Open() П> .Close() П> .Open() П> .Close() П> .Close(); П>}
А что если
x.Open().Close().Check();
И сыграть на констрейнтах к Check... ПРавда пока не очень представляю, как именно.
Здравствуйте, dotneter, Вы писали:
D>>>via reddit
П>>А слева от x ну вот совсем ничего нету (например, присвоения) или я зря голову уже час ломаю? D>В смысле A y = x? Пусть будет если нужно, но вообще не обязательно.
В оригинальном посте с reddit как раз обязательно. Но было бы любопытно увидеть решение в котором было бы необязательно (сомневаюсь только, что оно есть).
Я же написал, что главное в балансировке, как она будет достигнута не столь важно.
x.Open()... это псевдокод показывающий суть а не реализацию.
Можно использовать присвоение, можно return или вызов метода Check.
public class Foo
{
public Foo Open() { return this; }
public Foo Close() { return this; }
}
public sealed class Balancer<T> where T : Foo
{
int count = 0;
readonly T Target;
public Balancer(T target)
{
Target = target;
}
public Balancer<T> Open()
{
Target.Open();
++count;
return this;
}
public Balancer<T> Close()
{
Target.Close();
--count;
return this;
}
public bool Check()
{
return count == 0;
}
}
public static class BalancerExt
{
public static Balancer<T> OpenFirst<T>(this T obj) where T : Foo
{
return new Balancer<T>(obj).Open();
}
}
......
var ok = new Foo().OpenFirst().Open().Close().Close().Check();
}
Здравствуйте, dotneter, Вы писали:
D>На этапе компиляции проверить равенство количества вызовов Open и Close.
public class Box<T>
{
readonly private T value;
public Box(T value)
{
this.value = value;
}
public T Unbox() { return value; }
}
public static class Utils
{
public static Box<T> Open<T>(this T x)
{
return new Box<T>(x);
}
public static T Close<T> (this Box<T> box)
{
return box.Unbox();
}
}
class Program
{
static void Main()
{
int i = 1.Open().Open().Close().Open().Close().Close(); //OK
//int i = 1.Open().Close().Open().Close().Close(); //Error
}
}
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, dotneter, Вы писали:
D>>На этапе компиляции проверить равенство количества вызовов Open и Close.
K>
K> int i = 1.Open().Open().Close().Open().Close().Close(); //OK
K> //int i = 1.Open().Close().Open().Close().Close(); //Error
K>
Однако в условии нет указания по поводу того что Close должен быть обязательно после Open. Нужно лишь проверить равенство числа вызовов.
Здравствуйте, samius, Вы писали: S>А что если S>x.Open().Close().Check();
S>И сыграть на констрейнтах к Check... ПРавда пока не очень представляю, как именно.
Это примерно то же самое, что и с присваиванием, если считать что Check() — метод типа, к которому принадлежит значение x, констрейнты тут вообще не нужны, да и вообще с Check — не интересно.
А без Check или присваивания, я думаю, не сделать, ведь каждое подвыражение обязано быть корректным само по себе. Вот если бы компилятор выдавал ошибку "значение выражения ничему не присвоено" для всего кроме void, тогда можно было бы и без Check и без присваивания обойтись.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, samius, Вы писали:
S>Однако в условии нет указания по поводу того что Close должен быть обязательно после Open. Нужно лишь проверить равенство числа вызовов.
Да, это я домыслил. Но легко исправить:
public class Box<T>
{
readonly private T value;
public Box(T value)
{
this.value = value;
}
public T Unbox() { return value; }
}
public class AntiBox<T>
{
readonly private T value;
public AntiBox(T value)
{
this.value = value;
}
public T Unbox() { return value; }
}
public static class Utils
{
public static Box<T> Open<T>(this T x)
{
return new Box<T>(x);
}
public static T Close<T> (this Box<T> box)
{
return box.Unbox();
}
public static T Open<T>(this AntiBox<T> box)
{
return box.Unbox();
}
public static AntiBox<T> Close<T> (this T x)
{
return new AntiBox<T>(x);
}
}
class Program
{
static void Main()
{
int i = 1.Close().Open().Open().Close().Open().Close().Close().Open(); //OK
//int i = 1.Open().Close().Open().Close().Close(); //Error
}
}
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, samius, Вы писали:
S>>И сыграть на констрейнтах к Check... ПРавда пока не очень представляю, как именно.
K>Это примерно то же самое, что и с присваиванием, если считать что Check() — метод типа, к которому принадлежит значение x, констрейнты тут вообще не нужны, да и вообще с Check — не интересно.
Я тоже пришел к тому что нужно присванивание и рекурсивный полиморфизм. Но смутился замечанием ТС что присваивание не суть важно.
K>А без Check или присваивания, я думаю, не сделать, ведь каждое подвыражение обязано быть корректным само по себе. Вот если бы компилятор выдавал ошибку "значение выражения ничему не присвоено" для всего кроме void, тогда можно было бы и без Check и без присваивания обойтись.
угу
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Константин Л., Вы писали:
КЛ>>в с++ получилось бы еще красивее
S>Зачем так сложно? Достаточно варианта ув. Пельмешко: S>
Здравствуйте, dotneter, Вы писали:
D>Здравствуйте, Аноним, Вы писали:
D>Я же написал, что главное в балансировке, как она будет достигнута не столь важно. D>x.Open()... это псевдокод показывающий суть а не реализацию.
Ну код вроде автоматом понятен. Наследуем класс от IDisposable, в диспозе вызываем private/protected Close, open защищаем от повторного вызова. При таком методе просто невозможно получить разбалансировку и при этом Close вызывается автоматом при "неиспользовании" объекта. Можно и как-то по другом сделать, но важно чтобы Close вызывалось "автоматом", а не было доступно пользователю.
Re: [Этюд]Балансировка вызовов функций.
От:
Аноним
Дата:
25.02.11 08:47
Оценка:
А где это может потребоватся? Какой практический смысл такого кода?
Здравствуйте, Аноним, Вы писали:
А>А где это может потребоватся? Какой практический смысл такого кода?
Во первых, "этюд" может и не нести никакой пользы.
Во вторых, открывать и закрывать что-то приходится довольно часто.