CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    May 2001
    Location
    Silicon Valley
    Posts
    113

    Question Should a type for working with fractions be a class or a struct?

    Folks,

    I’m making a C# type for working with fractions, and trying to follow best practices. My question is: should a type like this be a class (reference type) or a struct (value type)?

    Here’s what I’m thinking.
    • Fraction is a kind of a number, which makes me think that it should be a value type, and therefore a struct.
    • System.Numerics.Complex has some similarities with a fraction type. Both represent a kind of a number. Both are small with only 2 numeric fields. System.Numerics.Complex is a stuct.

    At the same time, I’ve found a couple of existing articles on CodeProject, which describe Fraction types. Both of them are classes.
    Fraction class in C# [Syed Mehroz Alam, CodeProject, 2005]
    Fractions in C# [Nikola Stepan, CodeProject, 2005]
    The authors don’t explain why they chose to declare classes rather than structs. Something like that makes me think that there may be something that I don’t understand that was fairly obvious to them.

    Any suggestion, insight or reference is really appreciated!

    Cheers,
    - Nick

    P.S. For the most part, I work mostly with C and C++, where I have fine control over things like const, pointers, references. Of course, that comes at a risk of having nasty pointer-related bugs.
    Last edited by kender_a; October 8th, 2014 at 03:22 PM.

  2. #2
    Join Date
    Apr 2014
    Location
    in northeast ohio
    Posts
    94

    Re: Should a type for working with fractions be a class or a struct?

    i would much more lean towards struct since its math focused
    it is by its own definition dealing with values "fractions"
    alternatively static class or public sealed class / static methods

    in truth its more dependent on how the class needs to be used
    value or reference type is a bit of a oversimplification in this regard
    your really talking about copy semantics stack or heap and boxing considerations

    however the reality is
    these concerns are very usage specific probably to much so to be determinable until the struct or class is put to the test of usage

    i would refer you to this article by anders hejlsberg scrolling down
    to the section on value types sheds some light on the question
    http://www.artima.com/intv/choicesP.html

    by my understanding
    structs can at local scope be created droped on the stack then pop-ed off when done extremely efficiently
    value types n structs though can end up being boxed then must be un-boxed which is not so good

    to give a real world example
    xna was used for the xbox
    here performance was critical - the xbox has very low gc tolerance
    so they used struct for all the Vector Matrix Rectangle class's ect...
    this allowed for people to write basically zero garbage applications
    (or rather applications that had zero garbage collections) ,
    however it also allowed people to write applications that would box unbox the structs very bad on the xbox, if they were unaware of how the gc worked.
    but that same app on the pc were this pressure was not so severe the bad might be unoticable
    Last edited by willmotil; October 8th, 2014 at 05:42 PM.

  3. #3
    Join Date
    May 2001
    Location
    Silicon Valley
    Posts
    113

    Re: Should a type for working with fractions be a class or a struct?

    Thank you for the insight. I went ahead and created a struct and ran into the following problem.

    I can't have an explicit parameterless constructor. I can't have an instance field initializer like int m_denominator = 1;
    At the same time, the denominator can't be zero. Is it possible to initialize the denominator to 1 when the implicit constructor new Fraction(); is used? Is it possible to suppress the implicit parameterless constructor, and to prevent it from ever being called?
    The only solution I can think of at the moment, would be to implement the handling of the indeterminates (infinity and NaN) in this class. But that's a can of worms. [Could be a fun little can of worms, though... After all, this is a recreational programming effort.]

    I'm sure that I'm not the first one to run into an initialization issue like this.
    Last edited by kender_a; October 12th, 2014 at 01:26 AM.

  4. #4
    Join Date
    Apr 2014
    Location
    in northeast ohio
    Posts
    94

    Re: Should a type for working with fractions be a class or a struct?

    ok so i thought this was a interesting point
    i was looking for a way to get around this concern reasonably
    however after reading this old post from 5 years back
    which addresses nearly all the exact same points to a fraction class
    http://stackoverflow.com/questions/3...-struct-in-net

    im going to conclude which is better is not clear without a test case
    while ideologically struct would be correct
    due to technical reasons
    c# wants exclusive rights to a struct's default constructor
    ill point to this random guys quote which brings clarity to a important point

    A struct is a value type and a value type must have a default value as soon as it is declared.
    (this maybe the most important behavioral difference to remember with a struct)

    MyClass m;
    MyStruct m2;

    If you declare two fields as above without instantiating either, then break the debugger, m will be null but m2 will not. Given this, a parameterless constructor would make no sense, in fact all any constructor on a struct does is assign values, the thing itself already exists just by declaring it. Indeed m2 could quite happily be used in the above example and have its methods called, if any, and its fields and properties manipulated!
    in essence you cannot overide a c# struct default constructor
    because
    just declaring a struct m2; is equal to calling its default constructor as well
    the reasons are not perfectly clear... and its counter intuitive
    this is also similar to the behavior on property's with automatic get; set;
    and that's how it is in c# so,,,
    this would pose a real problem for the denominator returning a 0

    one thing you would need to prevent divide by 0
    is some access restriction via a property for example
    in combination with a check
    that the denominator is not returning or being set to zero in all case's
    something akin to this, though im not sure i like this idea
    a check on every call to get the denominator
    that sort of works against the benifit of using the stuct in the first place
    Code:
    public struct Frac
        {
            private int numerator;
            private int denominator;
    
            public int Numerator
            {
                get { return numerator; }
                set { numerator = value;  }
            }
            public int Denominator
            {
                get { if (denominator == 0) { denominator = 1; } return denominator; }
                set { denominator = value; }
            }
    }
    for that reason a class may actually be a better solution
    because now its even more so a matter of opinion
    until it can be proven in a usage context which is the better choice
    Last edited by willmotil; October 12th, 2014 at 09:25 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured