0

I'm learning lambdas and delegates in C# (and C# in general really), and I want to use these tools to manipulate member values of a struct. The struct is a Vector3, with x, y and z float values. The values are even to 0.5f in my structs (could be 3.5f, 13.5f etc.) and I want to even them out further to whole numbers (3.0f, 13.0f etc.). What I have so far is:

delegate Vector3 PosDelegate (Vector3 pos);

private void SomeFunction(){
   Vector3 position = getPositionFromSomewhere();

   PosDelegate evenPos = p => p.x -= 0.5f;
   evenPos += p => p.y -= 0.5f;

   Vector3 newPosition = evenPos(position);
}

I know the problem is that the delegate parameter definition doesn't match the output of the lambda (Vector3 and float mismatch) and I get the errors:

Cannot implicitly convert type 'float' to 'Vector3'

Cannot convert `lambda expression' to delegate type 'PosDelegate' because some of the return types in the block are not implicitly convertible to the delegate return type

but I'm not sure how to proceed. Explicitly casting doesn't work of course. Changing the lambda to something like

evenPos = p => (p.x, p.y, p.z) = (p.x - 0.5f, p.y -0.5f, 0.0f);

yields the same errors.

Any tips are greatly appreciated.

Community
  • 1
  • 1
HenrikMöller
  • 115
  • 1
  • 6

2 Answers2

2

Your delegate has to return a Vector3, not void. Thus simply write the following:

delegate Vector3 PosDelegate (Vector3 pos);

private void SomeFunction()
{
   Vector3 position = getPositionFromSomewhere();

   PosDelegate evenPos = p => new Vector { x = p.x - 0.5f, y = p.y - 0.5f };
   evenPos(position);
}

Be aware that struct are value-types. Thus whatever you get from getPositionFromSomewhere will completely be copied into a new instance of Vector3 and after calling the delegate copied a second time.

Making your delegate to not return anything (void) won´t work by the way, as the instance of Vector3 is copied when passed to the delegate. Thus every change you´re making within that delegate won´t be reflected outside it. See also why mutable structs are evil

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • Thank you! I had to use the syntax ´p => new Vector3 ( p.x - 0.5f, p.y - 0.5f, 0f);´ but that was a small adjustment. Yeah I'd rather not change the original struct. Now I just have to figure out a use case for the delegate, it's not very useful when doing all the work in one lambda. :) Thanks again! edit: sadly I have less than 15 rep so I can't +1 you.. – HenrikMöller Jan 26 '18 at 08:19
-1

You may just return new instance of Vector3 in delegate.