fork download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Linq.Expressions;
  6. using System.Reflection;
  7. using VisitorDelegate = System.Func<System.Linq.Expressions.Expression, System.Linq.Expressions.Expression>;
  8. using System.Diagnostics;
  9.  
  10. ///
  11. ///
  12. /// <remarks>http://b...content-available-to-author-only...n.com/b/alexj/archive/2010/03/01/tip-55-how-to-extend-an-iqueryable-by-wrapping-it.aspx</remarks>
  13. internal class InterceptingProvider : IQueryProvider
  14. {
  15. readonly IQueryProvider _underlyingProvider;
  16. readonly VisitorDelegate[] _visitors;
  17. readonly VisitorDelegate _afterUnderlyingVisitor;
  18.  
  19. private InterceptingProvider(VisitorDelegate afterUnderlyingVisitor,
  20. IQueryProvider underlyingQueryProvider,
  21. params VisitorDelegate[] visitors)
  22. {
  23. this._underlyingProvider = underlyingQueryProvider;
  24. this._afterUnderlyingVisitor = afterUnderlyingVisitor;
  25. this._visitors = visitors;
  26. }
  27.  
  28.  
  29. public static IQueryable<T> Intercept<T>(
  30. ExpressionVisitor afterUnderlyingVisitor,
  31. IQueryable<T> underlyingQuery,
  32. params ExpressionVisitor[] visitors)
  33. {
  34. Func<Expression, Expression>[] visitFuncs =
  35. visitors
  36. .Select(v => (Func<Expression, Expression>)v.Visit)
  37. .ToArray();
  38. VisitorDelegate afterDelegate = afterUnderlyingVisitor != null ? (VisitorDelegate)afterUnderlyingVisitor.Visit : null;
  39. return Intercept<T>(afterDelegate, underlyingQuery, visitFuncs);
  40. }
  41. public static IQueryable<T> Intercept<T>(
  42. IQueryable<T> underlyingQuery,
  43. params ExpressionVisitor[] visitors)
  44. {
  45. Func<Expression, Expression>[] visitFuncs =
  46. visitors
  47. .Select(v => (Func<Expression, Expression>)v.Visit)
  48. .ToArray();
  49. return Intercept<T>(null, underlyingQuery, visitFuncs);
  50. }
  51.  
  52. public static IQueryable<T> Intercept<T>(Func<Expression, Expression> afterUnderlyingVisitor,
  53. IQueryable<T> underlyingQuery,
  54. params Func<Expression, Expression>[] visitors)
  55. {
  56. var provider = new InterceptingProvider(afterUnderlyingVisitor,
  57. underlyingQuery.Provider,
  58. visitors
  59. );
  60. return provider.CreateQuery<T>(
  61. underlyingQuery.Expression);
  62. }
  63.  
  64. public static bool DoTrace {get;set;}
  65. public IEnumerator<TElement> ExecuteQuery<TElement>(
  66. Expression expression)
  67. {
  68. Expression intercepted;
  69. using(var step=Profiler.Step("intercepting query")){
  70. intercepted = InterceptExpr(expression);
  71. }
  72. IQueryable newExpression;
  73. using(var step=Profiler.Step("Ef Translating query")){
  74. newExpression = _underlyingProvider.CreateQuery(intercepted);
  75. }
  76.  
  77. System.Diagnostics.Debug.Assert(intercepted.Type.FullName.Contains("Shared") == false);
  78. if(DoTrace)
  79. using(var step=Profiler.Step("ToTraceString")){
  80. Trace.WriteLine(((System.Data.Objects.ObjectQuery)newExpression).ToTraceString());
  81. }
  82. if (_afterUnderlyingVisitor != null)
  83. {
  84. var afterResult = _afterUnderlyingVisitor(newExpression.Expression);
  85. }
  86. using(var step=Profiler.Step("enumerating query"))
  87. {
  88. var enumerator = newExpression.GetEnumerator();
  89. var enumeratorType = enumerator.GetType();
  90.  
  91. //get the type the enumerator contains
  92. var sourceArgumentType = enumeratorType.GetGenericArguments().Single();
  93.  
  94. var targetType = typeof(TElement);
  95. if (typeof(IEnumerator<TElement>).IsAssignableFrom(enumeratorType))
  96. return (IEnumerator<TElement>)enumerator;
  97.  
  98.  
  99. if (targetType.IsAssignableFrom(sourceArgumentType))
  100. {
  101. var items = new List<TElement>();
  102. while (enumerator.MoveNext())
  103. {
  104. var current = enumerator.Current;
  105.  
  106. items.Add((TElement)current);
  107. }
  108. if (enumerator is IDisposable)
  109. {
  110. (enumerator as IDisposable).Dispose();
  111. }
  112. return items.GetEnumerator();
  113. }
  114. //needs to translate one anonymous type to another
  115.  
  116. var targetConstructor = targetType.GetConstructor(targetType.GetGenericArguments());
  117. #warning does not handle recursive anonymous types
  118. var eProperties = from tp in targetType.GetProperties()
  119. join ep in sourceArgumentType.GetProperties()
  120. on tp.Name equals ep.Name
  121. select ep.GetGetMethod();
  122.  
  123.  
  124.  
  125. var items2 = new List<TElement>();
  126. while (enumerator.MoveNext())
  127. {
  128. var current = enumerator.Current;
  129. var targetParams = eProperties.Select(s => s.Invoke(current, null));
  130. var newItem = targetConstructor.Invoke(targetParams.ToArray());
  131.  
  132. items2.Add((TElement)newItem);
  133. }
  134. if (enumerator is IDisposable)
  135. {
  136. (enumerator as IDisposable).Dispose();
  137. }
  138. return (IEnumerator<TElement>)items2.GetEnumerator();
  139. }
  140. }
  141.  
  142. TResult TranslateAnonymous<TResult>(Type inputType, object source)
  143. {
  144. var targetType = typeof(TResult);
  145. if (targetType.IsAssignableFrom(inputType))
  146. return (TResult)source;
  147. var targetConstructor = targetType.GetConstructor(targetType.GetGenericArguments());
  148. #warning does not handle nested anonymous types
  149. var eProperties = from tp in targetType.GetProperties()
  150. join ep in inputType.GetProperties()
  151. on tp.Name equals ep.Name
  152. select ep.GetGetMethod();
  153. var targetParams = eProperties.Select(s => s.Invoke(source, null));
  154. var result = targetConstructor.Invoke(targetParams.ToArray());
  155. return (TResult)result;
  156. }
  157.  
  158. public IQueryable<TElement> CreateQuery<TElement>(
  159. Expression expression)
  160. {
  161. return new InterceptedQuery<TElement>(this, expression);
  162. }
  163.  
  164. public IQueryable CreateQuery(Expression expression)
  165. {
  166. Type et = TypeHelper.FindIEnumerable(expression.Type);
  167. Type qt = typeof(InterceptedQuery<>).MakeGenericType(et);
  168. object[] args = new object[] { this, expression };
  169.  
  170. var ci = qt.GetConstructor(
  171. BindingFlags.NonPublic | BindingFlags.Instance,
  172. null,
  173. new Type[] {
  174. typeof(InterceptingProvider),
  175. typeof(Expression)
  176. },
  177. null);
  178.  
  179. return (IQueryable)ci.Invoke(args);
  180. }
  181.  
  182. public TResult Execute<TResult>(Expression expression)
  183. {
  184. var intercepted = InterceptExpr(expression);
  185. var result = this._underlyingProvider.Execute(intercepted);
  186. if (result == null)
  187. return default(TResult);
  188. return TranslateAnonymous<TResult>(result.GetType(), result);
  189. }
  190.  
  191. public object Execute(Expression expression)
  192. {
  193. return this._underlyingProvider.Execute(
  194. InterceptExpr(expression)
  195. );
  196. }
  197.  
  198. private Expression InterceptExpr(Expression expression)
  199. {
  200. Expression exp = expression;
  201. foreach (var visitor in _visitors)
  202. exp = visitor(exp);
  203. return exp;
  204. }
  205. }
  206.  
  207.  
  208.  
  209. using System;
  210. using System.Collections.Generic;
  211. using System.Linq;
  212. using System.Text;
  213. using System.Linq.Expressions;
  214. using System.Reflection;
  215. using System.Diagnostics;
  216. using System.Collections;
  217.  
  218.  
  219. /// <remarks>http://stackoverflow.com/a/9120931/57883</remarks>
  220. public class TypeChangeVisitor : ExpressionVisitor
  221. {
  222. readonly IDictionary<Type, Type> _typeReplacements;
  223.  
  224. int visitStack = 0;
  225.  
  226. public TypeChangeVisitor(IDictionary<Type, Type> typeReplacements)
  227. {
  228. _typeReplacements = typeReplacements;
  229. var addItems = new Dictionary<Type,Type>();
  230. foreach (var item in typeReplacements.Keys)
  231. {
  232. if (item.IsInterface == false)
  233. continue;
  234. var interfaces = item.GetInterfaces();
  235. foreach (var i in interfaces)
  236. {
  237. if(_typeReplacements.ContainsKey(i)==false)
  238. addItems.Add(i,_typeReplacements[ item]);
  239. }
  240. }
  241. foreach (var item in addItems)
  242. _typeReplacements.Add(item.Key, item.Value);
  243.  
  244. }
  245.  
  246. IEnumerable<Type> TransformMethodArgs(MethodBase method)
  247. {
  248. //if(method.IsGenericMethod)
  249. //only generic methods should land here.
  250. foreach (var t in method.GetGenericArguments())
  251. {
  252. yield return VisitType(t);
  253. }
  254.  
  255.  
  256. }
  257. bool NeedsTypeChange(Type t)
  258. {
  259. var hasBadType = _typeReplacements.Keys.Any(k => t.FullName.Contains(k.FullName));
  260.  
  261. return hasBadType;
  262. }
  263. Type VisitType(Type t)
  264. {
  265. if (_typeReplacements.ContainsKey(t))
  266. {
  267. return _typeReplacements[t];
  268. }
  269. if (t.IsGenericType & t.GetGenericArguments().Any(NeedsTypeChange))
  270. {
  271. var types = t.GetGenericArguments().Select(VisitType).ToArray();
  272. var newType = t.GetGenericTypeDefinition().MakeGenericType(types);
  273. Debug.Assert(NeedsTypeChange(newType) == false);
  274. return newType;
  275. }
  276. Debug.Assert(NeedsTypeChange(t) == false);
  277. return t;
  278. }
  279. NewExpression TransformNewCall(NewExpression node)
  280. {
  281. Debug.Assert(node.Constructor != null);
  282.  
  283.  
  284.  
  285.  
  286. var argParams = node.Arguments.Select(n => Visit(n));
  287. Debug.Assert(argParams.Any(a => NeedsTypeChange(a.Type)) == false);
  288. var constructor = node.Constructor;
  289. //generic class constructor
  290. if (constructor.DeclaringType.IsGenericType && constructor.DeclaringType.GetGenericArguments().Any(NeedsTypeChange))
  291. {
  292.  
  293. var newType = VisitType(constructor.DeclaringType);
  294.  
  295. Debug.Assert(NeedsTypeChange(newType) == false);
  296. var constructorTypes = constructor.GetParameters().Select(s => s.ParameterType).Select(VisitType).ToArray();
  297. Debug.Assert(constructorTypes.Any(NeedsTypeChange) == false);
  298. constructor = newType.GetConstructor(constructorTypes);
  299. Debug.Assert(NeedsTypeChange(constructor.DeclaringType) == false);
  300. }
  301. var members = from fMember in node.Members
  302. join nMember in constructor.DeclaringType.GetMembers()
  303. on fMember.Name equals nMember.Name
  304. select nMember;
  305.  
  306. var membersTransformed = members.ToArray();
  307.  
  308. //Safe only because the from type is assumed to be an interface, and a new would be an anonymous type
  309. var visited = NewExpression.New(constructor, argParams, membersTransformed);
  310. Debug.Assert(visited.Members.Count == node.Members.Count);
  311. Debug.Assert(NeedsTypeChange(visited.Type) == false);
  312. return visited;
  313.  
  314. }
  315.  
  316. MethodCallExpression TransformMethodCall(MethodCallExpression node)
  317. {
  318. Debug.Assert(node.Method != null);
  319. var argTypes = TransformMethodArgs(node.Method).ToArray();
  320. Debug.Assert(argTypes.Any(NeedsTypeChange) == false);
  321. var argParams = node.Arguments.Select(n => Visit(n)).ToArray();
  322. Debug.Assert(argParams.Any(a => NeedsTypeChange(a.Type)) == false);
  323. var methodInfo = node.Method.GetGenericMethodDefinition().MakeGenericMethod(argTypes);
  324. Debug.Assert(NeedsTypeChange(methodInfo.DeclaringType) == false);
  325.  
  326. var visited = MethodCallExpression.Call(node.Object, methodInfo, argParams);
  327. Debug.Assert(NeedsTypeChange(visited.Type) == false);
  328. return visited;
  329. }
  330. protected override Expression VisitMethodCall(MethodCallExpression node)
  331. {
  332. Expression visited;
  333. if (node.Method != null && node.Method.ReturnType != null && NeedsTypeChange(node.Method.ReturnType))
  334. {
  335. var transformed = TransformMethodCall(node);
  336. Debug.WriteLine("Transformed methodcall");
  337. visited = base.VisitMethodCall(transformed);
  338. }
  339. else
  340.  
  341. if (node.Method != null && node.Arguments != null && node.Arguments.Any(t => NeedsTypeChange(t.Type)))
  342. {
  343.  
  344. var transformed = TransformMethodCall(node);
  345. Debug.WriteLine("Transformed methodcall");
  346. visited = base.VisitMethodCall(transformed);
  347. //node.Method.ReturnType.IsAssignableFrom(node.Arguments[0].Type)
  348. //node.Method.ReturnType.GetGenericArguments()
  349. //visited = node.Arguments[0];
  350.  
  351. }
  352. else
  353.  
  354. visited = base.VisitMethodCall(node);
  355. return visited;
  356. }
  357.  
  358. /// <remarks>http://stackoverflow.com/a/9120931/57883</remarks>
  359. protected override Expression VisitUnary(UnaryExpression node)
  360. {
  361. Expression visited;
  362. if (NeedsTypeChange(node.Type))
  363. {
  364. var operand = Visit(node.Operand);
  365. var newType = VisitType(node.Type);
  366. visited = Expression.MakeUnary(node.NodeType, operand, newType);
  367. }
  368. else visited = base.VisitUnary(node);
  369. //if (node.NodeType == ExpressionType.Convert
  370. //&& node.Type.IsAssignableFrom(node.Operand.Type))
  371. //{
  372. // return base.Visit(node.Operand);
  373. //}
  374. Debug.Assert(NeedsTypeChange(visited.Type) == false);
  375. return visited;
  376.  
  377.  
  378. }
  379.  
  380. protected override Expression VisitInvocation(InvocationExpression node)
  381. {
  382. var call = base.VisitInvocation(node);
  383. return call;
  384. }
  385.  
  386. public NewExpression LastNew { get; private set; }
  387. public NewExpression LastNewResult { get; private set; }
  388.  
  389. protected override Expression VisitNew(NewExpression node)
  390. {
  391. LastNew=node;
  392. Debug.WriteLine("Transforming NewExpression");
  393. Debug.WriteLine(ExpressionWriter.WriteToString(node));
  394. Debug.WriteLine(string.Empty);
  395. Expression visited;
  396. if (NeedsTypeChange(node.Type) || node.Arguments.Any(a => NeedsTypeChange(a.Type)))
  397. {
  398. var transformed = TransformNewCall(node);
  399.  
  400. Debug.Assert(NeedsTypeChange(transformed.Type) == false);
  401.  
  402. visited = base.VisitNew(transformed);
  403. }
  404. else
  405. visited = base.VisitNew(node);
  406. Debug.WriteLine("Transformed to");
  407. Debug.WriteLine(ExpressionWriter.WriteToString(visited));
  408. Debug.WriteLine(string.Empty);
  409. LastNewResult =(NewExpression) visited;
  410. return visited;
  411. }
  412. protected override Expression VisitConstant(ConstantExpression node)
  413. {
  414. Expression visited;
  415. if (NeedsTypeChange(node.Type))
  416. {
  417. if (node.Value == null)
  418. return ConstantExpression.Constant(null, VisitType(node.Type));
  419. var valueType = node.Value.GetType();
  420. //var newType=VisitType(node.Type);
  421. if (valueType.IsArray)
  422. {
  423.  
  424.  
  425. var value = node.Value;
  426. if (NeedsTypeChange(valueType)) //array is of bad type even though elements may not be
  427. {
  428. var elementType = valueType.GetElementType();
  429. var newElementType = VisitType(elementType);
  430.  
  431. var oldArray = (node.Value as Array);
  432. //var oArray = (object[])node.Value;
  433.  
  434. var newArray = Array.CreateInstance(newElementType, oldArray.Length);
  435. oldArray.CopyTo(newArray, 0);
  436. value = newArray;
  437. }
  438. else
  439. {
  440. //types in the array need changed, but the array itself does not
  441. //should never happen
  442. Debug.Assert(false);
  443. }
  444.  
  445. var transformed = ConstantExpression.Constant(value);
  446. visited = base.VisitConstant(transformed);
  447.  
  448.  
  449.  
  450. }else
  451.  
  452. visited = ConstantExpression.Constant(node.Value);
  453. }
  454. else visited = base.VisitConstant(node);
  455. Debug.Assert(NeedsTypeChange(visited.Type) == false);
  456. return visited;
  457. }
  458. public override Expression Visit(Expression node)
  459. { // general substitutions (for example, parameter swaps)
  460. if (node == null)
  461. return null;
  462. Expression found = null;
  463.  
  464. visitStack++;
  465.  
  466. found = base.Visit(node);
  467.  
  468. Debug.Assert(found == null || NeedsTypeChange(found.Type) == false);
  469.  
  470. visitStack--;
  471.  
  472. return found;
  473.  
  474. }
  475. protected override Expression VisitBinary(BinaryExpression node)
  476. {
  477. var newBinary = base.VisitBinary(node);
  478. return newBinary;
  479. }
  480.  
  481. /// <summary>
  482. /// In a given query the params must be the same instance, not just the same name/type
  483. /// </summary>
  484. /// <remarks>
  485. /// The parameter xxx was not bound in the specified LINQ to Entities query expression
  486. /// http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/8c2b0b1c-01bb-4de2-af46-0b4ea866cf8f
  487. /// </remarks>
  488. readonly Dictionary<ParameterExpression, ParameterExpression> paramMappings = new Dictionary<ParameterExpression, ParameterExpression>();
  489.  
  490.  
  491. protected override Expression VisitLambda<T>(Expression<T> node)
  492. {
  493.  
  494. Expression visited;
  495.  
  496.  
  497. if (NeedsTypeChange(node.ReturnType) || node.Parameters.Any(p => NeedsTypeChange(p.Type)))
  498. {
  499. var visitedBody = Visit(node.Body);
  500. Debug.Assert(NeedsTypeChange(visitedBody.Type) == false);
  501.  
  502. IList<ParameterExpression> transformedParams = new List<ParameterExpression>();
  503. foreach (var p in node.Parameters)
  504. {
  505. var transformedParam = VisitParameter(p);
  506. Debug.Assert(transformedParam is ParameterExpression);
  507. transformedParams.Add((ParameterExpression)transformedParam);
  508.  
  509. }
  510.  
  511. Debug.Assert(transformedParams.Any(t => NeedsTypeChange(t.Type)) == false);
  512.  
  513. var transformed = Expression.Lambda(visitedBody, transformedParams.ToArray());
  514. Debug.Assert(NeedsTypeChange(transformed.Type) == false);
  515.  
  516. Debug.Assert(NeedsTypeChange(transformed.ReturnType) == false);
  517. if (transformed is Expression<T>)
  518. {
  519. var transformedCasted = transformed as Expression<T>;
  520. visited = base.VisitLambda<T>(transformedCasted);
  521. }
  522. else
  523. visited = transformed;
  524. //return base.VisitLambda<T>(newLambda);
  525. }
  526. else
  527. visited = base.VisitLambda<T>(node);
  528. Debug.Assert(NeedsTypeChange(visited.Type) == false);
  529.  
  530.  
  531.  
  532. return visited;
  533. }
  534. protected override Expression VisitParameter(ParameterExpression node)
  535. {
  536. Expression visited = node;
  537.  
  538. if (NeedsTypeChange(node.Type))
  539. {
  540. ParameterExpression visitedParam = node;
  541. if (paramMappings.ContainsKey(node))
  542. {
  543. visited = base.VisitParameter(paramMappings[node]);
  544. }
  545. else
  546. {
  547. var newType = VisitType(visitedParam.Type);
  548. var newParam = Expression.Parameter(newType, node.Name);
  549. paramMappings.Add(node, newParam);
  550. visited = base.VisitParameter(newParam);
  551. }
  552.  
  553. }
  554. else
  555. visited = base.VisitParameter(node);
  556. Debug.Assert(NeedsTypeChange(visited.Type) == false);
  557. return visited;
  558. }
  559.  
  560. protected override Expression VisitMember(MemberExpression node)
  561. { // if we see x.Name on the old type, substitute for new type
  562. Expression visited = node;
  563.  
  564. if (NeedsTypeChange(node.Type) || NeedsTypeChange(node.Member.DeclaringType))
  565. {
  566. var newtype = VisitType(node.Member.DeclaringType);
  567.  
  568. var visitedExpression = Visit(node.Expression);
  569. Debug.Assert(NeedsTypeChange(visitedExpression.Type) == false);
  570. var targetProperty = newtype.GetProperty(node.Member.Name).GetGetMethod();
  571. //BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Single();
  572. visited = Expression.Property(visitedExpression, targetProperty);
  573. Debug.Assert(NeedsTypeChange(visited.Type) == false);
  574. visited = base.VisitMember((MemberExpression)visited);
  575. }
  576. else
  577. visited = base.VisitMember(node);
  578. Debug.Assert(NeedsTypeChange(visited.Type) == false);
  579. return visited;
  580. }
  581. }
  582.  
  583. using System;
  584. using System.Collections;
  585. using System.Collections.Generic;
  586. using System.Linq;
  587. using System.Text;
  588. using System.Linq.Expressions;
  589.  
  590.  
  591. internal class InterceptedQuery<T> : IOrderedQueryable<T>
  592. {
  593. private Expression _expression;
  594. protected internal readonly InterceptingProvider _provider;
  595.  
  596. internal InterceptedQuery(
  597. InterceptingProvider provider,
  598. Expression expression)
  599. {
  600. this._provider = provider;
  601. this._expression = expression;
  602. }
  603. public IEnumerator<T> GetEnumerator()
  604. {
  605. return this._provider.ExecuteQuery<T>(this._expression);
  606. }
  607. IEnumerator IEnumerable.GetEnumerator()
  608. {
  609. return this._provider.ExecuteQuery<T>(this._expression);
  610. }
  611. public Type ElementType
  612. {
  613. get { return typeof(T); }
  614. }
  615. public Expression Expression
  616. {
  617. get { return this._expression; }
  618. }
  619. public IQueryProvider Provider
  620. {
  621. get { return this._provider; }
  622. }
  623. }
  624.  
  625. using System;
  626. using System.Collections.Generic;
  627. using System.Linq;
  628. using System.Text;
  629. using System.IO;
  630. using System.Diagnostics;
  631.  
  632. public class DebugTextWriter : StreamWriter
  633. {
  634.  
  635. public DebugTextWriter(string category=null)
  636. : base(new DebugOutStream(category), Encoding.Unicode, 1024)
  637. {
  638. this.AutoFlush = true;
  639.  
  640. }
  641.  
  642. class DebugOutStream : Stream
  643. {
  644. readonly string _category = null;
  645. public DebugOutStream(string category)
  646. {
  647. _category = category;
  648. }
  649. public override void Write(byte[] buffer, int offset, int count)
  650. {
  651. if (String.IsNullOrEmpty(_category))
  652. Debug.Write(Encoding.Unicode.GetString(buffer, offset, count), _category);
  653. else
  654. Debug.Write(Encoding.Unicode.GetString(buffer, offset, count));
  655. }
  656.  
  657. public override bool CanRead { get { return false; } }
  658. public override bool CanSeek { get { return false; } }
  659. public override bool CanWrite { get { return true; } }
  660. public override void Flush() { Debug.Flush(); }
  661. public override long Length { get { throw new InvalidOperationException(); } }
  662. public override int Read(byte[] buffer, int offset, int count) { throw new InvalidOperationException(); }
  663. public override long Seek(long offset, SeekOrigin origin) { throw new InvalidOperationException(); }
  664. public override void SetLength(long value) { throw new InvalidOperationException(); }
  665. public override long Position
  666. {
  667. get { throw new InvalidOperationException(); }
  668. set { throw new InvalidOperationException(); }
  669. }
  670. };
  671. }
  672. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty