C# does not support pointer arithmetic by default to have type safety and security.
If we want to use pointers in C# we need to use the keyword unsafe. We can have pointer types, value types and reference types in an unsafe context. When we declare multiple pointers in a single declaration, the * is written together with the type only.
For example:

Pointers can also be used in the parameter list, because the scope of the unsafe context is from parameter list to the
end of the method.

We can also declare a block of statements as unsafe.
For example;

unsafe
{
// Statements in the block
}

This block is an unsafe block and we can declare pointers inside this block.

1. A pointer cannot point to a reference or to a struct that contains references because an object reference can be garbage collected even if a pointer is pointing to it. The garbage collector does not keep track of whether an object is being pointed to by any pointer types.
2. In some cases unsafe code may increase an application’s performance by removing array bounds checks.
3. Unsafe code introduces stability and security risks.

*Note: Unsafe codes are not verifiable by the common language runtime.