BrandonAGr
BrandonAGr

Reputation: 6017

Design of method using ref to alter partially immutable class

In my project I have a header class that represents a globally unique key for a piece of information inside the system, such as who it belongs to, what time it exists for, etc. Inside the same header class I also have fields for information that is specific to a given instance of data, such as who created this version of the information, when it was created, if its new data that needs to be saved to the database, etc.

Here is an example of stocking some information into a data transport class and querying it back out.

var header = new IntvlDataHeader(
       datapoint: Guid.NewGuid(),
       element: Guid.NewGuid(),
       intervalUtc: DateTime.Now.Date);

package.StockData_Decimal(header, 5m);

decimal cloneData;
package.TryGetData_Decimal(ref header, out cloneData);

// header now refers to a different object, that could have different flags/information

Note how I made the TryGetData_Decimal pass the header variable by reference. IntvlDataHeader is a class, and if the data is found inside TryGetData then the reference is changed to point to a new instance of IntvlDataHeader that has the specific instance information in addition to having the same unique key information.

Is combining a key with instance specific information and using a ref parameter as both in and out a bad design? Would the effort of splitting out another class so that there would be two out parameters and no ref parameters be better or avoid any potential problems?

The signature of the method is public bool TryGetData_Decimal(ref IntvlDataHeader header, out decimal data)

Upvotes: 4

Views: 120

Answers (1)

David Hoerster
David Hoerster

Reputation: 28701

I think the naming of your TryGetData_Decimal is misleading, if the ref parameter your passing in will then point to a new instance when the method exits. TryGetData_Decimal, to me, sounds like a variation of the TryParse methods on a number of value types (which has an out parameter containing the parsed value - similar to the cloneData parameter).

I guess I'm not sure why the header object has to point to a new instance, so I'm not sure I can recommend a design. If that's what you need to do, I think it may be more readable if your TryGetData_XXX methods have a signature something like this:

IntvlDataHeader ExtractValueAndGetNewInstance_Decimal(IntvlDataHeader header, out decimal cloneData)

where header is passed in, but doesn't change when the method exits. The method returns the new instance, and you can use it if you need it. I wouldn't change the cloneData - I think out parameters are OK as long as they aren't overused.

I'd try to change the name of the method to something more meaningful, too.

I hope this helps.

Upvotes: 2

Related Questions