Implicit array casting in C# - c#

I have the following classes with an implicit cast operator defined:
class A
{
...
}
class B
{
private A m_a;
public B(A a)
{
this.m_a = a;
}
public static implicit operator B(A a)
{
return new B(a);
}
}
Now, I can implicitly cast A to B.
But why can't I implicitly cast A[] to B[] ?
static void Main(string[] args)
{
// compiles
A a = new A();
B b = a;
// doesn't compile
A[] arrA = new A[] {new A(), new A()};
B[] arrB = arrA;
}
Thanks, Malki.

As Mehrdad Afshari mentioned, you're out of luck doing this implicitly. You'll have to get explicit, and it'll involve an array copy. Thankfully, you can probably do it with a one-liner:
arrB = arrA.Cast<B>().ToArray();
Although if you only want to iterate arrB in a foreach statement, you can avoid the copy by omitting ToArray()

Array covariance only works for reference types and in the inheritance hierarchy (note that it's not a representation-changing conversion: just a set of pointers with identical size interpreted differently.) It will not work for value types and user defined conversions.

ConvertAll
Just to be explicit, here is how you use ConvertAll.
In the case where class B has a member of class A called m_a, do this:
B[] arrB;
A[] arrA = Array.ConvertAll(arrB, b => b.m_a);
.
If class B has some member data that you need to manipulate before you can return an object of type A (such as turning a bunch of numerical values into a string description), do this:
class B
{
public static A makeAfromB(B b)
{
// Do something with B data...
A a = new A("data made from B data")
return a;
}
// rest of class B implementation ...
}
// somewhere else in your code...
A[] arrA = Array.ConvertAll(arrB, new Converter<B, A>(B.makeAfromB));
.
You can also use Lambda functions:
A[] arrA = Array.ConvertAll(arrB, new Converter<B, A>(
delegate(B b)
{
// Do something with B data, though object b is const
A a = new A("data made from B data")
return a;
}));
.
It would be nice if ConvertAll could use the implicit operator to do the conversion, but I haven't figured out how to do that.
.
Cast
#Randolpho #bottlenecked
For the cases where you simply want to iterate and would prefer not to make a copy, using cast makes sense. However I have been unable to make it work.
I have an InkPoint class which has a Point object and some other members. I want to call the DrawLines(Pen, Point[]) function. However, I have an array of InkPoint[].
Here is my class and the code I currently have to use, which makes a copy:
public class InkPoint
{
public InkPoint(int x, int y)
{
point = new Point(x, y);
}
public Point point { get; set; }
public static implicit operator Point(InkPoint p)
{
return p.point;
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
InkPoint[] inkPoints = { new InkPoint(1,2), new InkPoint(3,4) };
Point[] points = Array.ConvertAll(inkPoints, x => x.point);
Pen pen = new Pen(Color.Black, 1);
e.Graphics.DrawLines(pen, points);
}
.
I would rather call this, but it won't compile, citing invalid arguments:
e.Graphics.DrawLines(pen, inkPoints.Cast<Point>()); // Compile err: invalid args
.
I've also tried iterating over a cast, but it throws an exception, citing the cast is not valid
foreach (Point p in inkPoints.Cast<Point>()) { } // Exception: cast not valid
.
I don't understand why the specified cast is not valid since I've defined an implicit operator. I'm able to do the following just fine:
InkPoint ip = new InkPoint(10, 20);
Point p1 = ip; // implicit conversion
Point p2 = (Point)ip; // cast
.
For me, the situation is actually slightly more complicated than that. I actually have a list of InkPoints, List<InkPoint>, but the DrawLines function accepts only arrays. So my code looks like this:
List<InkPoint> inkPoints = new List<InkPoint>();
inkPoints.Add(new InkPoint(5, 10));
inkPoints.Add(new InkPoint(10, 15));
Point[] points = inkPoints.ConvertAll<Point>(x => x.point).ToArray();
I can rearrange it slightly to this:
Point[] points = Array.ConvertAll(inkPoints.ToArray(), x => x.point);
.
So I think there's actually two copies happening here. This is annoying since all I want to do is draw the lines. It doesn't seem unreasonable that the DrawLines function should be able to iterate over some array/list that contains references to objects that can be implicitly converted to Point objects.

Imagine for a moment if Arrays used the same syntax as other collections in .Net, and what you're trying to compare is an Array<A> with an Array<B>. You wouldn't compare a List<A> to a List<B>. Well, that's essentially what you're trying.
I'd recommend using a simple extension method to get the result you want, you'll need to change your syntax slightly to say 'B[] arrB = arrA.ToBArray();`
static class ArrayCast {
public static B[] ToBArray(this A[] source) {
var result = new B[source.Length];
for (int i = 0;i < source.Length;i++)
result[i] = source[i];
return result;
}
}

Related

List always does not contain array even it is

I am trying to check if list of arrays contains array with factors in reverse order and if not, add them:
var faclist = new List<int[]>();
var factors = new int[2] {i, j};
if (!faclist.Contains(factors.Reverse()))
{
faclist.Add(factors);
}
However this code always not true even there are arrays with reversed factors.
The .Contains works on the .Equals method. By default, the .Equals method returns only true, if the two instances (references) are the same.
A possible way to solve this - if the number of factors are fixed - is using a Tuple<int,int>. You can define the Reverse method on a `Tuple class with:
public static class Foo {
public static Tuple<T2,T1> Reverse<T1,T2> (this Tuple<T1,T2> tuple) {
return new Tuple<T2,T1>(tuple.Item2,tuple.Item1);
}
}
And then call it simply with:
Tuple<int,int> t = new Tuple<int,int>(3,5);
Tuple<int,int> t2 = t.Reverse();
If not, you could define a wrapper class, that performs the equality check as described here.
Or another alternative, is to provide an equality checker yourself in the .Contains method as described by #xanatos answer.
Demo:
$ csharp
Mono C# Shell, type "help;" for help
Enter statements below.
csharp> var t1 = new Tuple<int,int>(3,2);
csharp> var t2 = new Tuple<int,int>(3,2);
csharp> t1.Equals(t2);
true
csharp> int[] t1 = new int[] {3,2};
csharp> int[] t2 = new int[] {3,2};
csharp> t1.Equals(t2);
false
As written by CommuSoft, because arrays don't implement comparison in the way you think (they do only reference comparison)
Another solution is to implement an equality comparer:
public class IntArrayComparison : IEqualityComparer<int[]> {
public bool Equals(int[] x, int[] y) {
if (x == null) {
return y == null;
}
if (y == null) {
return false;
}
return x.SequenceEqual(y);
}
public int GetHashCode(int[] obj) {
throw new NotImplementedException();
}
}
if (!faclist.Contains(factors.Reverse().ToArray(), new IntArrayComparison())) {
And then use it in the Contains method. (note that I have to change the result of Reverse() back to an array, because Reverse() returns an IEnumerable<T>)

Possible to get reference of "operator" result?

Is it somehow possible to get the reference of the result of an overloaded operator in C# so you don't have to use the "new" keyword to create a temp result (which is returned afterwards)?
Here's an example of a problem I ran into:
public class Stats {
public float someField;
public float someOtherField;
public static Stats operator +(Stats a, Stats b) {
Stats c = new Stats(); // I don't want a new one, can I access operators result directly?
c.someField = a.someField + b.someField;
c.someOtherField = a.someOtherField + b.someOtherField;
return c;
}
/*
// This is what I want to achieve, but it would be cooler if static and with the "+"
public Add(SomeType a) {
someField += a.someField;
someOtherField += a.someOtherField
}
*/
}
public class StatObserver {
public Stats statsToObserve;
public Output() {
print(statsToObserve.someField);
}
}
public class Class {
public Stats firstStats = new Stats();
firstStats.someField = 1.5f;
public StatObserver showStats = new StatObserver();
showStats.statsToObserve = firstStats;
public Stats nextStats = new Stats();
nextStats.someField = 3.4f;
// now the tricky part
firstStats += nextStats; // C# handles the += itself correctly
showStats.Output(); // prints "1.5"
// you have to update the observer to get the new value
// it's kind of stupid, because you have to treat firstStats like a value type buts its not
showStats.statsToObserve = firstStats;
showStats.Output(); // prints "4.9"
}
You can't overload the += operator directly - it is compiled to an add and an assignment. You could mutate the left-hand side as part of the + operator - but that would be evil. An Add method seems to be the cleanest design IMHO.
First things first, as #D.Stanley notes, you can't override +=. You can override +, as you have done, but there is something important to realize about +:
Math operators are non-destructive, that is, they return a result
without modifying the operands
That being said, you could modify the properties of operands in a reference type (which this is), but you shouldn't. So don't. The good news is, your + operation is correct.
Because of this, you have to return a new object (as you do), but when you do the += you assign the local reference to this new object, while leaving the observer's reference pointing at the old object, causing your error.
You probably want to modify the observer directly:
showStats.statsToObserve += nextStats;
Or, you could totally hack it and do this (not recommended):
public static Stats operator +(Stats a, Stats b) {
Stats c = new Stats();
c.someField = a.someField + b.someField;
a.SomeField += b.someField; //AHHHH You just modified an operand!
c.someOtherField = a.someOtherField + b.someOtherField;
a.someOtherField += b.someOtherField; //AHHHH You just did it again!
return c;
}
Note: I like #DStanley's recommendation as well for the solution to this.

Generic Sqrt Implementation

I'm using the MiscUtils library (thanks Marc G. and Jon S.) and am trying to add a generic Sqrt function to it. The problem can be easily reproduced with this:
class N<T>
{
public N(T value)
{
Value = value;
}
public readonly T Value;
public static implicit operator T(N<T> n)
{
return n.Value;
}
public static implicit operator N<T>(T value)
{
return new N<T>(value);
}
public static T operator /(N<T> lhs, T rhs)
{
// Operator.Divide is essentially a wrapper around
// System.Linq.Expressions.Expression.Divide
return Operator.Divide(lhs.Value, rhs);
}
}
// fails with: No coercion operator is defined
// between types 'System.Double' and 'N`1[System.Single]'.
var n = new Numeric<float>(1f);
var x = Operator.DivideAlternative(n, 1.0);
// this works as the N<T> is first converted to a
// float via the implicit conversion operator
var result = n / 1.0;
Now, I realize why this is happening, but I have not yet been able to think of a way around it. For reference, here is the current Sqrt implementation. I have little experience building expression trees.
public static double Sqrt<T>(T value)
{
double oldGuess = -1;
double guess = 1;
while(Abs(guess - oldGuess) > 1)
{
oldGuess = guess;
// the first evaluated call to DivideAlternative throws
guess = Operator.Divide(
Operator.AddAlternative(guess,
Operator.DivideAlternative(value, guess)),
2);
}
return guess;
}
EDIT: Ok, so I solved this on my own, but in an attempt to keep the question as simple as possible I apparently went too far and spent far too much time answering questions from confused people trying to help.
So, this is the problem in its entirety.
I two classes; one that performs transformations and another which performs statistical analysis of image data (pixels). Let's focus on the latter as the problem is the same:
abstract class ImageStatistics
{
private readonly object _pixels;
public ImageStatistics(object pixelArray)
{
Pixels = pixelArray;
}
// calculate the standard deviation of pixel values
public double CalcStdDev();
}
The array of pixels can be any numeric type. In practice, it will be either float, int, ushort, or byte. Now, because generics cannot do things like this:
public T Add<T>(T lhs, T rhs)
{
return lhs + rhs; // oops, no operator + for T
}
I cannot perform any sort of statistical analyses on the pixel values themselves without casting to the proper array type. So, I need to have N sub-classes of ImageProcessor to support N pixel types.
Well, that sucks. I would love to just have a generic ImageProcessor<T> class which has a T[] of pixel data. So, I looked into the MiscUtils library which would allow just this.
Math.Sqrt needs a double, so why not just provide it with one?
public static double Sqrt<T>(T value)
{
return Math.Sqrt(Convert.ToDouble(value));
}
You might also consider casting to dynamic.
public static double Sqrt<T>(T value)
{
return Math.Sqrt((dynamic) value);
}
This technique can also be used for operators like addition:
public static T Add<T>(T a, T b)
{
return (dynamic) a + (dynamic) b;
}
Console application creating array of objects (unknown types) and calculating square route (double)
using System;
namespace GenericSqrt
{
class Program
{
static void Main(string[] args)
{
var array = new object[] { "2", null, 4.1f, 4.444D, "11.3", 0, "Text", new DateTime(1, 1, 1) };
foreach (var value in array)
{
try
{
Console.WriteLine(Sqrt(value));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.ReadLine();
}
private static double Sqrt(object value)
{
double converterValue = Convert.ToDouble(value);
return Math.Sqrt(converterValue);
}
}
}
Output looks like this:
1.4142135623731
0
2.02484564958235
2.10807969488822
3.36154726279432
0
Input string was not in a correct format.
Invalid cast from 'DateTime' to 'Double'.
If type is indeed any of number types, as you stated, there is no problem to solve.
Let me preface this by saying it probably isn't worth the effort, considering how this code would need to be maintained. I wrote this in about 10 minutes, so don't expect anything too spectacular.
// You'll need this
public interface ISquareRootHelper
{
double Sqrt<T>(T value)
where T : struct;
}
class Program
{
private static ISquareRootHelper helper;
// Build the helper
public static void BuildSqrtHelper()
{
// Let's use a guid for the assembly name, because guid!
var assemblyName = new AssemblyName(Guid.NewGuid().ToString());
// Blah, blah, boiler-plate dynamicXXX stuff
var dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var dynamicModule = dynamicAssembly.DefineDynamicModule(assemblyName.Name);
var dynamicType = dynamicModule.DefineType("SquareRootHelper");
// Let's create our generic square root method in our dynamic type
var sqrtMethod = dynamicType.DefineMethod("Sqrt", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual);
sqrtMethod.SetReturnType(typeof(double));
// Well, I guess here is where we actually make the method generic
var genericParam = sqrtMethod.DefineGenericParameters(new[] {"T"});
genericParam[0].SetGenericParameterAttributes(GenericParameterAttributes.NotNullableValueTypeConstraint);
// Add a generic parameter, and set it to override our interface method
sqrtMethod.SetParameters(genericParam);
dynamicType.DefineMethodOverride(sqrtMethod, typeof(ISquareRootHelper).GetMethod("Sqrt"));
// Magic sauce!
var ilGenerator = sqrtMethod.GetILGenerator();
// Math.Sqrt((double)value);
ilGenerator.Emit(OpCodes.Ldarg_1); // arg_0 is this*
ilGenerator.Emit(OpCodes.Conv_R8);
var mathSqrtMethodInfo = typeof(Math).GetMethod("Sqrt");
ilGenerator.EmitCall(OpCodes.Call, mathSqrtMethodInfo, null);
ilGenerator.Emit(OpCodes.Ret);
// Since we're overriding the interface method, we need to have the type
// implement the interface
dynamicType.AddInterfaceImplementation(typeof(ISquareRootHelper));
// Create an instance of the class
var sqrtHelperType = dynamicType.CreateType();
helper = (ISquareRootHelper)Activator.CreateInstance(sqrtHelperType);
}
public static void Main(string[] args)
{
BuildSqrtHelper();
Console.WriteLine(helper.Sqrt((short)64)); // Works!
Console.WriteLine(helper.Sqrt((ushort)64)); // Works!
Console.WriteLine(helper.Sqrt((int)64)); // Works!
Console.WriteLine(helper.Sqrt((uint)64)); // Works*!
Console.WriteLine(helper.Sqrt((byte)64)); // Works!
Console.WriteLine(helper.Sqrt((sbyte)64)); // Works!
Console.WriteLine(helper.Sqrt((float)64)); // Works!
Console.WriteLine(helper.Sqrt((double)64)); // Works!
Console.WriteLine(helper.Sqrt((long)64)); // Works!
Console.WriteLine(helper.Sqrt((ulong)64)); // Works*!
// Let's try non-primitives!
Console.WriteLine(helper.Sqrt(DateTime.Now)); // Doesn't fail, but doesn't actually work
Console.WriteLine(helper.Sqrt(Guid.NewGuid())); // InvalidProgramException!
}
}
Anyway, I guess this proves it can be done. Just make sure when you use it, you only pass in primitive types, otherwise all fail will break loose. Actually, it will only throw an exception when you pass in a struct that is a greater size that 8 bytes, since that will unbalance the stack. You can't do a check like sizeof(T) in the method though, because it would fail during the JITing process.
Also, there are some *s next to some of the types up there. There is some extra logic done by the compiler and/or Math.Sqrt when you pass in unsigned numbers vs signed numbers, and how this related to negative numbers. For example:
Console.WriteLine(Math.Sqrt(unchecked((uint)-2))); // 65535.9999847412
Console.WriteLine(helper.Sqrt(unchecked((uint)-2))); // NaN :(
You could improve it and checks above to catch that, though. Also, I don't recommend this solution, especially if you're not comfortable with IL. Plus, this is probably more verbose and complicated than just writing a bunch of different methods to handle the operations you want.
This works, but it's a bit ugly:
public static implicit operator Numeric<T>(double value)
{
return new Numeric<T>((T)Convert.ChangeType(value, typeof(T)));
}
public static implicit operator double(Numeric<T> n)
{
return Convert.ToDouble(n.Value);
}
It will have to be repeated for each supported type, which makes this a lot less generic. I slapped an IConvertible constraint on there for good measure. If anyone has a better solution I'm all ears.

how to reference a value in a C# array

i have the following array :
int[] myArray = {21,21,364,658,87};
and a reference to the second element like so:
int rr = myArray[1];
i want something like :
rr = 500
Console.writeLine(myArray[1]);// ---> should print 500 !
i hope you guys got my idea , i can do this easily in python like the example above.
so
how to do this in C#
my solution would probably be create property with arr[1] as its backing property
something like:
public int rr
{
set{ arr[1] = value;}
get{ return arr[1];}
}
and than rr=500; will be the same as arr[1]=500;
You could use something like this:
public static class ArrayExtensions
{
public static Action<int> CreateSetter(this int[] array, int index)
{
return (value) => array[index] = value;
}
}
[TestFixture]
public class ArrayTest
{
[Test]
public void Test()
{
int[] myArray = {21,21,364,658,87};
Action<int> rr = myArray.CreateSetter(1);
rr(500);
Assert.AreEqual(500, myArray[1]);
}
}
When you do this:
int[] myArray = {21,21,364,658,87};
int rr = myArray[1];
rr = 500;
You will only overwrite the value in rr, there is no way for you to get the actual memory address of an arrays inner elements, and thereby updating it.
My answer must therefore be:
myArray[1] = 500;
I'm trying to understand what you're trying to do, if you want to encapsulate your change in a function you could pass the reference on this way, but it's all about what you want to do with it:
public void Proc()
{
var ints = new [] { 1, 2, 3, 4 };
FunctionChangingByReference(ref ints[1]);
}
public void FunctionChangingByReference(ref int x)
{
x = 500;
}
In C# there are no pointers, only references.
(I'm lying a bit, you could use pointers if you create a unsafe context, but we don't do that in C#, and neither should you. When we code C++ we do, but that's C++, and we do it at a cost, we make the code a bit more fragile and error prone. When I code C# I try to optimize the code on a higher level than memory address shuffling. If you really need to optimize on that level you should write the code in C++ and import that code as a dll, then you have a good separation of concern, and don't forget to test drive the development!)
Simply myArray[1] = 500! You could use a property as Nahum Litvin has suggested if you specifically want a reference to a specific integer within the array.
#des answer has awaken my interest. So I tried his solution and it works as expected:
int[] numbers = new[] { 1, 2, 3 };
fixed (int* number = &numbers[0])
{
*number = 10;
}
Console.WriteLine(String.Join(", ", numbers)); // Outputs "10, 2, 3"
You have to compile it with the /unsafe option.
I hope you see that this may bring some problems.
Therefore I don't recommend this solution.
What you want is a basically pointer to a variable.
It's hard to explain the difference between "value type" (like int or struct), a reference and a pointer. I can only recommend learning C.
Here's solution that works, although it may need a lot of changes to your code.
//a class that will hold an int inside
public class myIntWrapper
{
//this is the value wrapper holds
public int theValue;
//constructor taking the value
public myIntWrapper(int argument)
{
theValue = argument;
}
//operator to convert an int into brand-new myIntWrapper class
public static implicit operator myIntWrapper(int argument)
{
return new myIntWrapper(argument);
}
//operator to convert a myIntWrapper class into an int
public static implicit operator int(myIntWrapper wrapper)
{
return wrapper.theValue;
}
}
now you can write:
//create an array -
//setting values to every item in array works
//thanks to operator myIntWrapper(int argument)
myIntWrapper[] myArray = new myIntWrapper[5]{1,2,3,4,5};
//now take a "reference"
myIntWrapper rr = myArray[1];
//change the value
rr.theValue = 500;
//from now on myArray[1].theValue is 500;
//thanks to operator int(myIntWrapper wrapper)
//you can write:
int ss = rr;//it works!
please remember to never do:
rr = 600;
because this will actually create brand new myIntWrapper, that's not "connected" anywhere.
So remember:
rr.theValue = 500;//this changes the value somewhere
rr = myArray[3];//this changes where rr is "pointing" to
Yes, it's quite complicated but I doubt it can be done any simpler without unsafe code. I'm sorry for not explaining it more. I'll answer to all questions in comments.

Closures and java anonymous inner classes

Would anyone be so kind to post the equivalent Java code for a closure like this one (obtained using C#) with anonymous inner classes?
public static Func<int, int> IncrementByN()
{
int n = 0; // n is local to the method
Func<int, int> increment = delegate(int x)
{
n++;
return x + n;
};
return increment;
}
static void Main(string[] args)
{
var v = IncrementByN();
Console.WriteLine(v(5)); // output 6
Console.WriteLine(v(6)); // output 8
}
Furthermore, can anyone explain how partial applications can be obtained if lexical closures are available and viceversa? For this second question, C# would be appreciated but it's your choice.
Thanks so much.
There is no closure yet in Java. Lambda expressions are coming in java 8. However, the only issue with what you're trying to translate is that it has state, which not something that lamba expressions will support i don't think. Keep in mind, it's really just a shorthand so that you can easily implement single method interfaces. You can however still simulate this I believe:
final AtomicInteger n = new AtomicInteger(0);
IncrementByN v = (int x) -> x + n.incrementAndGet();
System.out.println(v.increment(5));
System.out.println(v.increment(6));
I have not tested this code though, it's just meant as an example of what might possibly work in java 8.
Think of the collections api. Let's say they have this interface:
public interface CollectionMapper<S,T> {
public T map(S source);
}
And a method on java.util.Collection:
public interface Collection<K> {
public <T> Collection<T> map(CollectionMapper<K,T> mapper);
}
Now, let's see that without closures:
Collection<Long> mapped = coll.map(new CollectionMapper<Foo,Long>() {
public Long map(Foo foo) {
return foo.getLong();
}
}
Why not just write this:
Collection<Long> mapped = ...;
for (Foo foo : coll) {
mapped.add(foo.getLong());
}
Much more concise right?
Now introduce lambdas:
Collection<Long> mapped = coll.map( (Foo foo) -> foo.getLong() );
See how much nicer the syntax is? And you can chain it too (we'll assume there's an interface to do filtering which which returns boolean values to determine whether to filter out a value or not):
Collection<Long> mappedAndFiltered =
coll.map( (Foo foo) -> foo.getLong() )
.filter( (Long val) -> val.longValue() < 1000L );
This code is equivalent I believe (at least it produces the desired output):
public class Test {
static interface IncrementByN {
int increment(int x);
}
public static void main(String[] args) throws InterruptedException {
IncrementByN v = new IncrementByN() { //anonymous class
int n = 0;
#Override
public int increment(int x) {
n++;
return x + n;
}
};
System.out.println(v.increment(5)); // output 6
System.out.println(v.increment(6)); // output 8
}
}
Assuming we have a generic function interface:
public interface Func<A, B> {
B call A();
}
Then we can write it like this:
public class IncrementByN {
public static Func<Integer, Integer> IncrementByN()
{
final int n_outer = 0; // n is local to the method
Func<Integer, Integer> increment = new Func<Integer, Integer>() {
int n = n_outer; // capture it into a non-final instance variable
// we can really just write int n = 0; here
public Integer call(Integer x) {
n++;
return x + n;
}
};
return increment;
}
public static void main(String[] args) {
Func<Integer, Integer> v = IncrementByN();
System.out.println(v.call(5)); // output 6
System.out.println(v.call(6)); // output 8
}
}
Some notes:
In your program, you capture the variable n by reference from the enclosing scope, and can modify that variable from the closure. In Java, you can only capture final variables (thus capture is only by value).
What I did here is capture the final variable from the outside, and then assign it into a non-final instance variable inside the anonymous class. This allows "passing info" into the closure and at the same time having it be assignable inside the closure. However, this information flow only works "one way" -- changes to n inside the closure is not reflected in the enclosing scope. This is appropriate for this example because that local variable in the method is not used again after being captured by the closure.
If, instead, you want to be able to pass information "both ways", i.e. have the closure also be able to change things in the enclosing scope, and vice versa, you will need to instead capture a mutable data structure, like an array, and then make changes to elements inside that. That is uglier, and is rarer to need to do.

Categories