skip to Main Content

I’m trying to create a record type in C# with some fields as fixed length strings.

I just want to use this record for further reading of a predefined file format.

I tried this:

  public record Person (int  age, fixed char  birthdate[8]);

However, I’m getting the following error

Array size cannot be specified in a variable declaration (try initializing with a ‘new’ expression)CS0270

I’m using the Visual Studio Code Version: 1.88.1 (Universal).

Can you help me?

Thanks in advance,
Mario

2

Answers


  1. First of all, the best path to folllow is use of Datetime as the comments said, but if you can’t, you could throw an Exception on the record constructor:

    public record Person
    {
        public int Age { get; set; }
        public string Birthdate { get; set; }
        public Person(int age, string birthdate)
        {
            if (birthdate.Length == 8)
                throw new ArgumentException("Birthdate must be exactly 8 characters long.");
    
            Age = age;
            Birthdate = birthdate;
        }
    }
    

    With this, the first example will pass, but the second will throw the exception

    var validPerson = new Person(1, "012345678");
    var invalidPerson = new Person(1, "0123456789");
    
    Login or Signup to reply.
  2. Fixed-length buffers can be defined as fields on an unsafe structs. This approach can help reduce the need for garbage collection when memory is sparse.

    But they cannot be used as fields on record types (not even record struct), and they cannot be used as parameters to methods or constructors, as you appear to be trying to do. You would need to take another type (a string or a Span<char> or maybe a char*) as an argument, and perform any length validation at run-time.

    unsafe
    {
        Person foo = new Person(25, "01011995");
    
        Console.Write("Birthdate: ");
        char* bd = foo.birthdate;
        {
            for (int i = 0; i < 8; i++)
            {
                Console.Write(bd[i]);
            }
        }
        Console.WriteLine();
    }
    
    
    public unsafe struct Person 
    {
        public int age;
        public fixed char birthdate[8];
    
        public Person(int age, ReadOnlySpan<char> date)
        {
            if (date.Length != 8)
            {
                throw new ArgumentException("Date must be exactly 8 characters long.");
            }
    
            this.age = age;
            fixed (char* b = birthdate)
            fixed (char* d = date)
            {
                Buffer.MemoryCopy(d, b, 8 * sizeof(char), 8 * sizeof(char));
            }
        }
    }
    
    

    But I should point out that this is (as the keyword says) unsafe, and the vast majority of C# developers don’t need to get this low-level. Most people are fine using things like strings and DateTimes.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search