0

I have a static class 'Defaults' which shall hold default matrices that are forwarded to an interface that asks for double[][] in the end. So far I simply put static properties in this class that return double[][]s.

Now to make this conform to our company's coding standards, the code must comply to FxCop's rule CA1819, which won't allow me to return a jagged array from a property like I did. And instead of arrays, I shall return IList or IEnumerable (as discussed here).

"Fair enough" I thought, so I implemented the property to return IList<IList<double>> (although nested types are uncool too). However, as I said, the interface which I need to work with asks for double[][] matrices in the end.. I have no idea how to get this list of lists into an array of arrays without explicitly converting back each list. Of course, I could, but that would create an insane amount of overhead, especially since I don't even access those matrices - I only pass them through to the interface.

(PS: I know, it's the Interface's fault, but at the moment we can't change that.)

Edit: I found out that using ILists<IList<double>> donesn't help anyway, since it violates CA1006. The easy solution that I took to make FxCop shut up was to make the properties internal. Anyway, the nicer solution is stated below. Alternatively, one may consider to use an indexed property, which is a bit messy in C# though.

Community
  • 1
  • 1
Efrain
  • 3,248
  • 4
  • 34
  • 61

2 Answers2

2

I suggest, you create a class Matrix<T> that accepts a T[][] into its constructor and can be converted to T[][] and make your properties in Defaults return a Matrix<double> instance. The conversion can either be implemented implicitly, explicitly or using a method.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • Better still, create a Matrix class and then you can reuse it in the future for other data types. – pstrjds Jul 06 '11 at 12:21
  • Yep, that sounds good. I'll think about it next time I have to deal with that interface... AND actually do something with those matrices myself - since it's a rather small thing I'm implementing at the moment. [see comments in ageektrapped's answer] – Efrain Jul 06 '11 at 12:42
0

The FxCop rule is there to prevent confusion for the user of the API and to remind the API author if that's what they really want to do.

Returning an array as a property is a potential for API consumers to wreak havoc on an internal data structure, which is probably not the intent of the API author.

From the rule linked:

Arrays returned by properties are not write-protected, even if the property is read-only. To keep the array tamper-proof, the property must return a copy of the array. Typically, users will not understand the adverse performance implications of calling such a property. Specifically, they might use the property as an indexed property.

One of the ways they recommend for returning an array is to change an Xxx property to a GetXxx() method.

Is that possible for you?

ageektrapped
  • 14,482
  • 7
  • 57
  • 72
  • I think FxCop would then complain that you should change the Get to a property :) – pstrjds Jul 06 '11 at 12:21
  • Yeah, it's a little brain dead, but then one can ignore that violation, hopefully. FxCop is not something to be blindly followed. – ageektrapped Jul 06 '11 at 12:22
  • Meh, yeah, possible, but then I can just (illegally) ignore CA1819 in the first place. Actually: I just made all defaults internal, not pretty, but whatever. One can actually access the defaults through the interface itself, so there's no theed for this Defaults class to be public. – Efrain Jul 06 '11 at 12:38
  • Well, then I'd say FxCop is doing its job. The whole point of that tool is to force you to consider your public API. You noticed that Defaults shouldn't be public, which is better for your API and removes the FxCop violations. Internal is a very powerful concept and should be used frequently in frameworks. It's definitely not 'not pretty'. :) – ageektrapped Jul 06 '11 at 12:43