0

Is it possible to do something like the following in C#?

unsafe string GetName()
{
    Foo[] foo = new Foo[2]; // Create an array of Foo and add two Foo elements
    foo[0] = new Foo { Name = "Bob" };
    foo[1] = new Foo { Name = "Jane" };

    Foo *ptr = &foo;    // Get address of the first element in the array
    ptr++;  // Move to the next element in the array

    return *ptr.Name;  // Expect Name to be "Jane"
}

I'm playing around with custom data structures, and I would like to be able to do this.

I know you can do it with int types etc, but what about user defined structs and classes?

user1515024
  • 181
  • 9

1 Answers1

7

You can do this, but only if Foo is a struct where all the fields are "unmanaged types". int is an unmanaged type; string is not. You should use the fixed statement to fix the array in place so that the garbage collector does not move it. Consult chapter 18 of the specification, and note that when you turn the safety system off, it is off. That means that you are responsible for understanding everything about memory management in C# when you write unsafe code. Do you understand everything about memory management? If the answer is "no" then do what I do: don't write unsafe code. I've been writing C# code for ten years and haven't had to write unsafe code (aside from compiler test cases) yet.

You simply should not do this in the first place. There's no need to use unsafe code. If you want something that acts like a pointer to the middle of an array you can do that in a typesafe manner without using pointers.

Here, I've even written the code for you:

http://blogs.msdn.com/b/ericlippert/archive/2011/03/10/references-and-pointers-part-two.aspx

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Hey thanks for your concise answer! I certainty don't pretend to know more then the high level memory model for C#, I'm basically just doing this for fun. The code above would never be used for production, I'm just attempting to make a generic thread-safe structure that's even faster then a singled threaded hashtable for example. More importantly I'm teaching myself some low level techniques that I fear I'm currently lacking. I will read parts one and two of your blog entry, cheers. – user1515024 Jan 24 '14 at 14:31
  • @user1515024: That's a good learning exercise. This would also be an opportunity to study the C# memory model, which is a lot weaker than the x86 memory model. You'll also probably find that generics and pointers do not mix well in C#. – Eric Lippert Jan 24 '14 at 14:53
  • I've been playing around with your ArrayPtr code, it's pretty cool, I like it. But I have one question, why is it a struct instead of a class? If I want to use this on a large array, will that cause problem (or is the source array on the heap)? I see you made the struct in a functional pattern, I assume this is for thread safety? In your ArrayPtr, whats the pros of a struct over a class? I have never once used a struct (or seen one) in production code, perhaps I'm ill-informed? Thanks in advance. – user1515024 Jan 24 '14 at 21:35
  • @user1515024: You have five questions, not one. First: I made it a struct because it is a **value type** because it is (1) very small, and (2) **logically a value**. – Eric Lippert Jan 24 '14 at 22:08
  • @user1515024: Second: all arrays are on the heap in C#. Arrays are *reference* types, not *value types* because they are (1) large, and (2) do not behave like *values*. – Eric Lippert Jan 24 '14 at 22:09
  • @user1515024: Third: No, I care not a whit about thread safety. You should always make value types immutable because mutable value types are a worst practice in C#. Think about it like this: when you add 1 to 2, you don't **mutate 2 into 3**. 2 stays the same. The result of the addition is a *new thing*. If 2 could magically change into 3, that would be confusing. Values should always be treated as *values*, not *variables*. Treat *variables* as variables. – Eric Lippert Jan 24 '14 at 22:11
  • @user1515024: Fourth: This is a frequently asked question on this site. Look it up. – Eric Lippert Jan 24 '14 at 22:11
  • @user1515024: Fifth: Many C# developers are very ill-informed about the semantics of value types. I have written extensively on this subject. This would be a good place to start: http://blogs.msdn.com/b/ericlippert/archive/tags/value+types/ -- start from the bottom, those are in reverse chronological order. – Eric Lippert Jan 24 '14 at 22:13
  • 1
    Thanks for answering all of those, five for the price of one! – user1515024 Jan 24 '14 at 22:22