Придумать программу, в которой можно поменять какую-то пару круглых скобок на квадратные, а программа при этом останется компилируемой.
Скобки, разумеется, должны быть токенами (то есть не должны быть внутри комментария, строки, названия региона, или секции, исключённой с помощью директив препроцессора).
Существует, по крайней мере, три способа.
Здравствуйте, nikov, Вы писали:
N>Придумать программу, в которой можно поменять какую-то пару круглых скобок на квадратные, а программа при этом останется компилируемой. N>Скобки, разумеется, должны быть токенами (то есть не должны быть внутри комментария, строки, названия региона, или секции, исключённой с помощью директив препроцессора). N>Существует, по крайней мере, три способа.
Ну первое что приходит в голову:
using System;
class Program
{
static void Main()
{
var f = new Foo(1);
var f2 = new Foo[1];
}
}
class Foo
{
public Foo(int p) { }
}
Здравствуйте, nikov, Вы писали:
N>Придумать программу, в которой можно поменять какую-то пару круглых скобок на квадратные, а программа при этом останется компилируемой. N>Скобки, разумеется, должны быть токенами (то есть не должны быть внутри комментария, строки, названия региона, или секции, исключённой с помощью директив препроцессора). N>Существует, по крайней мере, три способа.
Про C# 4.0 ничего не было сказано...
sealed class Foo : System.Dynamic.DynamicObject
{
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
result = new object();
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
result = new object();
return true;
}
static void Main(string[] args)
{
dynamic foo = new Foo();
var t = foo(0);
var t = foo[0];
}
}
Здравствуйте, nikov, Вы писали:
N>Существует, по крайней мере, три способа.
Эвона как:
using System;
class A
{
public int this[int v]
{
get { return v; }
}
}
class B
{
public A A
{
get { return new A(); }
}
}
static class C
{
static public int A(this B b, int _)
{
return 1;
}
}
class Program
{
static void Main()
{
var b = new B();
var x1 = b.A[1];
var x2 = b.A(1);
}
}
Здравствуйте, Oyster, Вы писали:
O>Здравствуйте, nikov, Вы писали:
N>>Существует, по крайней мере, три способа.
O>Эвона как:
И это был третий способ!
7.4 Member lookup
If the simple-name or member-access occurs as the primary-expression of an invocation-expression (§7.6.5.1), the member is said to be invoked.
If a member is a method or event, or if it is a constant, field or property of either a delegate type (§15) or the type dynamic (§4.7), then the member is said to be invocable.
....
• Next, if the member is invoked, all non-invocable members are removed from the set.
Здравствуйте, nikov, Вы писали:
N>И это был третий способ!
А я опять поторопился Индексер тут, конечно, ни при чём (а я всё так хотел его куда-нибудь впихнуть), а вот метод-расширение причём:
using System;
class B
{
public int[] A
{
get { return new [] { 1 }; }
}
}
static class C
{
static public int A(this B b, int _)
{
return 1;
}
}
class Program
{
static void Main()
{
var b = new B();
var x1 = b.A[0];
var x2 = b.A(0);
}
}
Здравствуйте, nikov, Вы писали:
N>Придумать программу, в которой можно поменять какую-то пару круглых скобок на квадратные, а программа при этом останется компилируемой. N>Скобки, разумеется, должны быть токенами (то есть не должны быть внутри комментария, строки, названия региона, или секции, исключённой с помощью директив препроцессора). N>Существует, по крайней мере, три способа.
using System;
public class A
{
}
public class B
{
public static B operator +(B b)
{
return null;
}
public static explicit operator A[](B b)
{
return null;
}
public static A[] operator +(int i, B b)
{
return null;
}
}
class Program
{
static Func<int> A;
static B b;
static void Main(string[] args)
{
A[] c;
c = (A[]) + b;
c = (A()) + b;
}
}
Вроде ещё одно уникальное. Я даже название этому решению придумал.
"Абстракционизм"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace test
{
class Program
{
public interface IIndexable
{
int this[int a]
{
get;
}
}
public interface IHaveMethod
{
int MethodOrProp(int i);
}
public abstract class HaveProp
{
public abstract IIndexable MethodOrProp
{
get;
}
}
public class MethodOrPropRunner<MethodOrPropObject>
where MethodOrPropObject : HaveProp, IHaveMethod
{
void Run(MethodOrPropObject objToRun)
{
int result = objToRun.MethodOrProp[1]; //<<--HERE
}
}
static void Main(string[] args)
{
}
}
}
Здравствуйте, Oyster, Вы писали:
N>>Кстати, можно было бы обойтись instance методом.
O>А как? Я метод-расширение использвал, чтобы обойти запрет на члены с одинаковым именем... как без него — что-то не понимаю.
Ну, например, определить их на разных уровнях иерархии наследования, чтобы поле/свойство типа int[] скрывало метод с таким же именем.