13

I started to learn about C# and I usually use C++. There are a bunch of things that I'm trying to adapt, but std::array seems impossible...

I just want to run this kind of code:

public struct Foo {};
public struct Test 
{ 
    public Foo value[20]; 
};

I don't want to allocate each time I use this struct and I don't want to use a class ever... I saw the fixed keyword but it works only for basic types... There is no equivalent to something as simple as std::array? I can even do that in C.

How would you solve this problem? (Even if it's still dynamically allocated..)

9
  • 8
    You don't want to use a class ever? What C# tutorials are you reading? Commented Dec 13, 2018 at 19:40
  • 2
    Not using a class ever? C#? I think you need to do some more learning before starting to code in C#. (Not trying to be snarky at all - just I think you are jumping the gun if you are trying to write C# code with no classes!!!) Commented Dec 13, 2018 at 19:48
  • 1
    Writting a class just to have a constructor to allocate a amount of memory that I know when I write the struct... I'd like my code to not be that ineficient. Not even in a performance point of view (I know I would have to sacrifice things with C#) but I'm trying to not sacrifice everything thing that make my C++ efficient to write. So the question is how would you automate this simple task? I'm okay with unsafe, but fixed dosn't work with custom type. Commented Dec 13, 2018 at 19:53
  • 1
    In C#, you shouldn't use a struct ever. (Well, almost). Commented Dec 13, 2018 at 20:17
  • 4
    @MathieuVanNevel - You can check this design guideline article which states As a rule of thumb, the majority of types in a framework should be classes. It also gives some pretty explicit guidelines for when you should use a struct and ends that with this statement In all other cases, you should define your types as classes. This answer over at softwareengineering.se gives some good guidelines as well. Commented Dec 13, 2018 at 21:12

4 Answers 4

4

Using a fixed size buffer (fixed) is only possible for primitive types since its use is intended for interop. Array types are reference types, and so they can have dynamic size:

public struct Test 
{ 
    public Foo[] value; 
}

Note however that copying the struct will only copy the reference, so the arrays will be identical. I suggest you either make the type immutable (by disabling writing to the array), or change struct to class and control cloning explicitly.

There is no such thing as a fixed size by-value array type in C# (although I have proposed it once). The closest thing you can get to it is a value tuple.

Sign up to request clarification or add additional context in comments.

2 Comments

So I guess a class with some inheritance would be the more convenient code I would find here? I should probably add some convertion to Unity NativeArray if needed. Sad but at least it won't be that horrible to write. Thanks :)
Probably not gonna work that easily... I'll try to find my answer later on
2

Since .NET 8 you may want to use the InlineArrayAttribute, if the array has a (maximum) size, which is known at compile-time.

[System.Runtime.CompilerServices.InlineArray(20)]
internal struct MyFixedSizeBuffer
{
    private Foo item;
}

This way (additional) heap allocations can be avoided by stack-allocating the buffer:

MyFixedSizeBuffer b = new MyFixedSizeBuffer(); // allocation on the stack
b[0] = new Foo();
b[19] = new Foo();

or by embedding it into classes:

class MyClass
{
    private MyFixedSizeBuffer b;
}

See Inline Arrays for reference.

Comments

0

So it seems like there is no way to not do something as stupid as dynamically allocate something know at compile time. But that's C# so I just need to... try to close my eyes. Anyway I did something to solve array alias and fixed array at the same time (I didn't ask about array alias on this question thought).

public abstract
class Array<T>
{
  private T[]  data;

  protected Array(int size) { data = new T[size]; }
  public T this[int i]
  {
    get { return data[i]; }
    set { data[i] = value; }
  }
};

public Alias : Array<int>
{
  static public int Length = 10;
  public Area() : base(Length) {}
};

And some people say it's quicker to write code with C#... If someone have better I'll glady take it!

6 Comments

There are Spans now, and you can have a read-only property to minimize the potential for run-time re-allocation.
@JoelCoehoorn Wait C# introduced stackalloc and Spans are kind of the safe way to use it? So I can do some kind of std::array (not constexpr obviously) now? I prefer to ask you directly because it feels too nice :)
Read here, and make sure to get to at least the 2nd example: msdn.microsoft.com/en-us/magazine/mt814808.aspx
@JoelCoehoorn I did read it, just wanted your confirmation :) Thanks!
What is the difference between this and simply using T[]?
|
-4

In C# Array is very simple

        // string[] arr = new string[3]; Examole 1
        // string[] arr = {"","","",""}; Example 2
         // string[] arr = new string[]{"abdul ","araheman"};


        // arr[0] = "abdul";
        // arr[1] = "Rahman";
        // arr[2] = "Nadap"; 

        //foreach(var a in arr)
        //{
        //    Console.WriteLine(a);
        //}

1 Comment

Thank you for contributing to the Stack Overflow community. This may be a correct answer, but it’d be really useful to provide additional explanation of your code so developers can understand your reasoning. This is especially useful for new developers who aren’t as familiar with the syntax or struggling to understand the concepts. Would you kindly edit your answer to include additional details for the benefit of the community?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.