As with C++, structs in C# can have private members. The big difference between structs and classes, though, is that structs are value types. This means that, for example, function local usage of struct instances can forego allocating them on the heap and instead allocate them in the program's activation records (stack frames).
Because of the semantic differnces you can't just go switching all your classes to structs and realize a significant performance difference. Code like this:
class Foo
{
int bar;
}
public static void Func(Foo[] arrayOfFoos)
{
Foo f = arrayOfFoos[0];
f.bar = 10;
}
will break in subtle ways because you are no longer manipulating the heap allocated instance via a reference but rather a copy that was allocated local to the function.
Arrays of structs also have better cache locality which can improve performance on number crunching workloads and can also make it easier to exchange data between managed code and native code through a P/Invoke interface.