Kamil Solecki
Kamil Solecki

Reputation: 1117

Private struct as a return type of a public method

I'm building a class which goal is to read, process and output MNIST data.

For the purpose of cleaniness, i decided i would want the user to be able to access only the data reading method, Readfile().

I tried to figure out the best way to return the data, and have fiddled with:

  1. Tuples, but as you can judge from the code it got incredibly ugly and barely readable.
  2. ExpandoObjects
  3. Structs (as in code below)

As for now, I've been wondering wether it's possible to return a private struct in a public method, and maybe catch it in a var type to further process it like an object.

All I really want to achieve is to return an object that cannot be accessed directly by calling the MNISTReader class.

Code:

abstract class MNISTReader
{
    // Define structs that hold our data.
    public struct DataPair
    {
        List<byte> Labels { get; set; }
        List<Matrix<byte>> Images { get; set; }

        public DataPair(List<byte> labels, List<Matrix<byte>> images)
        {
            this.Labels = labels;
            this.Images = images;
        }
    }

    public struct Data
    {
        DataPair Train { get; set; }
        DataPair Validation { get; set; }
        DataPair Test { get; set; }

        public Data(DataPair train, DataPair validation, DataPair test)
        {
            this.Train = train;
            this.Validation = validation;
            this.Test = test;
        }
    }

    // Method for reading the files and obtaining data.
    public static Data ReadFile()
    {

        // IMAGE PROCESSING (CUT OUT)

        DataPair train = new DataPair(trainLabels, trainImages);
        DataPair validation = new DataPair(validationLabels, validationImages);
        DataPair test = new DataPair(testLabels, testImages);

        return new Data(train, validation, test);
    }
}

Upvotes: 2

Views: 1396

Answers (2)

D Stanley
D Stanley

Reputation: 152556

You can't return a private type from a public function. The only way to do that is to make the return type of your public function object, since all types derive from it, or dynamic, which defers all type checking and method binding to run-time. However, some drawbacks if either choice are:

  • The caller has no idea what type will be returned, what properties it has, etc
  • Any coding errors (typos, etc) will not be discovered until run-time

All I really want to achieve is to return an object that cannot be accessed directly by calling the MNISTReader class.

One thing you can do is make the constructor internal, that way only the assembly it's in can create instances. But the type needs to be public if you want clients to be able to use its properties or methods.

I would also note that nothing in your requirements indicates that DataPair should be a struct. The choice to make something a struct are more about its value-type semantics than its accessibility.

Upvotes: 3

David
David

Reputation: 218827

If a method returns a type, then that type needs to be "as visible" as the method itself.

This is simply because the consuming code needs to be able to understand the object being returned. Whether it's a class or struct makes no difference in this regard. C# is a statically typed language and so the compiler needs to be able to guarantee that any code which consumes that method will be aware of the return type.

It's very common for libraries to "hide" internal types and simply expose some structs/DTOs/etc. publicly for consumers of the library to interact with it. Just keep your struct public so consumers of the public method will be able to understand it.

If you don't want that particular type to be visible outside of the class/library/etc., create another type for the purpose of consuming code to receive the data. A simple DTO with no functionality on it (which, well, is what you already have in the posted code really) would do the job nicely.

Upvotes: 1

Related Questions