简体   繁体   中英

How to expose internal System.Array

I have a class that is a container for two fixed length arrays as well as some other members. I want to expose the elements of the array for assignment outside the class.

Example would be:

    using System.Collections.ObjectModel;

    class ArrayContainer<T, U>
    {
       private T[] x;
       private U[] y;

       // Some other members and constructor

       public Collection<T> X
       {
            get { return new Collection<T>(this.x); }
       }

       public Collection<U> Y
       {
           get { return new Collection<U>(this.y); }
       }
    }

If I try to do instance.X[i] = value I get an exception saying the collection is readonly. So I have three questions:

  1. Why can't I make the above assignment?
  2. Is this the correct was to expose internal members?
  3. Are there any performance issues with making a "new" Collection every time the array is created?

Answer to 3: Your performance is definitely at issue; you'd be creating a new instance each time it was accessed. Any time a person wrote a for... loop you'd get a new instance for each iteration.

Why not publicly just expose your collections? I might do the same thing by simply using List:

class Data<T,U> {
    public List<T> X = new List<T>();
    public List<U> Y = new List<U>();
}

Writing code would be quite simple:

        Data<int, string> theData = new Data<int, string>();
        // add
        theData.X.Add(37);
        theData.Y.Add("foo");
        // access
        theData.X[0] = 42;
        theData.Y[0] = "bar";
        // as an array
        int[] x = theData.X.ToArray();

If performance really creeps you out, just use arrays instead of List<T>.

  1. Not sure, but since you are returning a new Collection, it doesn't matter what you do to it. The changes will be lost once the Garbage Collector deletes the Collection. Changes made to the collection will not affect the original array.

  2. No, the correct way would be to either expose the arrays directly, or, if you're worried clients won't play nice, expose them via getters and setters. Since C# only allows 1 property per class with arguments you'll have to use functions for this:

     instance.SetX(int index, T value); T val = instance.GetX(int index); 
  3. Yes, making copies always takes extra time and memory. If this is performance critical code, this solution is not acceptable, otherwise, it's probably fine.

If you familiar with concept of interfaces, then you can choose or code the interface explaining what should be external. Then add interface to you class declaration and compiler will help you to do the rest of things properly since.

I have no idea what this is for, but why not use indexers or getter/setter methods? I would think that that would be the typical way of doing this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM