Search code examples
c#conditional-statementsoperator-keywordfixedternary

Using ternary conditional operator in fixed statement


Main aim is made the subroutine more unify, and have possibility in SET assignments select the field of struct based on value of Variable. If I replace current fixed() on commented row with fixed(), I receive error CS0212.

Why it can't work - It's a "current limitation of C#4.0" or it can't work in principle?

    enum ConnectSide {Left,Right}

    unsafe private void ConnectSubtreeToNewNode(int iNumNodeHeadSubtree, int iNumNewNode, ConnectSide Side)
    {
        //fixed (int* prtNode = (Side == ConnectSide.Left) ? &Tree[iNumNewNode].iLeftElement : &Tree[iNumNewNode].iRightElement )
        fixed (int* prtNode = &Tree[iNumNewNode].iLeftElement)
        {
            if (iNumNodeHeadSubtree != iNodeOFF)
            {
                *prtNode = iNumNodeHeadSubtree;
                Tree[iNumNodeHeadSubtree].iParentElement = iNumNewNode;
            }
            else
                *prtNode = iNodeOFF;
        }
    }

additionally

        private Node[] Tree;
        //Main struct for BST
        public struct Node
        {
            public int Key;
            public int iLeftElement;
            public int iRightElement;
            public int iParentElement;
            public int iHeight;
            public int iBalance;
        }

Solution

  • As noted here the operator & can only be used to take the address of an unfixed variable directly inside a fixed statement initializer. By trying to use & inside the ternary operator you break that premise about the usage of &.

    You can do something like this though:

        // first fix the variable that you want to make a change later on (Tree[iNumNewNode]).
        fixed (var lpTree = &Tree[iNumNewNode])
        {
            // here you can create the pointer you wanted using the ternary operator.
            int* ptrNode = (Side == ConnectSide.Left) ? &lpTree->iLeftElement : &lpTree->iRightElement;
    
            if (iNumNodeHeadSubtree != iNodeOFF)
            {
                *prtNode = iNumNodeHeadSubtree;
                Tree[iNumNodeHeadSubtree].iParentElement = iNumNewNode;
            }
            else
                *prtNode = iNodeOFF;
        }