Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Track two types of values within one variable

Track two types of values within one variable

Scheduled Pinned Locked Moved C#
beta-testingquestioncode-review
26 Posts 10 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S SledgeHammer01

    It doesn't make much sense to have a Rate class if all it does is contain a double. Is there more to it then that? Is the Rate used elsewhere? I'm gonna go out on a limb and say that TransactionLine should just have a double Rate property and a RateType enum property that says whether its a % or $ amount.

    H Offline
    H Offline
    hpjchobbes
    wrote on last edited by
    #4

    Thanks for the response! The enum seems like it would be a simpler way to handle this. Since the Rate may be used in multiple different classes, I think I should go with an enum in the Rate class.

    public enum ENRateType { Dollar, Percent }

    public class Rate
    {
    public ENRateType RateType;
    public double Rate;
    }

    1 Reply Last reply
    0
    • H hpjchobbes

      I'm still new, so I don't know if this is the best way to do what I am needing, and would like some feedback/advice. I have a class that contains a double value. This double could represent a dollar value or it could represent a percentage value. Only one or the other, it will never have both. At runtime, I will need to be able to tell what type of value this is. Here is what I came up with, which appears to work, but if there is a better way, I would prefer that.

      public class Rate
      {
      public double Value; // Holds either the dollar or percentage value
      }
      public class RateDollar : Rate {}
      public class RatePercentage : Rate {}

      public class TransactionLine
      {
      // There's more stuff here, but it's not relevant to show
      public Rate Amount;
      }

      // Set the rate amount to be a dollar
      myTransactionLine.Amount = new RateDollar();

      // I can check the type if needed
      if(myTransactionLine.Amount.GetType() == typeof(RateDollar)) // We have a dollar value
      if(myTransactionLine.Amount.GetType() == typeof(RatePercent)) // We have a percentage value

      For some reason, this seems like it is a clunky workaround. It also seems like it's possible for someone to create the value that is neither a RateDollar or RatePercent, and just as a plain Rate. Is there some way to prevent this, or is there a better way to accomplish what I am trying to do?

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #5

      A quick and dirty solution;

      public class Rate
      {
      public double Value; // Holds either the dollar or percentage value

      public override string ToString ()
      {
      	string typeName = GetType().Name;
      	// removes the prefix, if present
      	if (typeName.StartsWith(typeof(Rate).Name))
      		typeName = typeName.Substring(typeof(Rate).Name.Length);
      	return typeName;
      }
      

      }
      // Console.WriteLine(myTransactionLine.Amount);
      // would then result in "Dollar" as output

      It'd be cleaner to introduce a new property than to abuse the ToString-method. Putting an enum in there that returns "Dollar" or "%" would require the base-class to have knowledge thereof. ..unless you introduce an abstract property that returns an object. Yes, that introduces an extra cast in the calling code, but that could easily be wrapped in a utility-method.

      Bastard Programmer from Hell :suss: if you can't read my code, try converting it here[^]

      H 1 Reply Last reply
      0
      • L Lost User

        Use an interface rather than a class. It seems to make more sense I think Note: you could also use an abstract class... But I would go with the interface as you do not actually need logic at the base level...

        public interface IRate
        {
        double Value { get; set;}
        }

        public class RateDollar : IRate
        {
        public double Value { get; set;}
        }
        public class RatePercentage : IRate
        {
        public double Value { get; set;}
        }

        The thing I find odd is why are you doing a type check? If you are doing type checks this is often a red flag of 2 objects that really should not have a direct relation (sometimes). If you provide more detail I am sure someone can give some more advice. But as it stands I would say just use an interface.

        Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

        H Offline
        H Offline
        hpjchobbes
        wrote on last edited by
        #6

        Thanks for responding! I haven't really gotten to learning a lot about interfaces (or abstract classes), but I am thinking that will be the next topic I tackle. The reason for this setup is because I am interacting with another software, and that software has one value that represents either a dollar value or a percentage. For example, this is how it would show a transaction:

        Widget $12.00
        Shipping $3.95
        Subtotal $15.95
        Tax 8.875%
        Total $30.11

        When I get this information from the program, they have a rate class that contains three members, an enum for the price type (dollar or percent), a double for the Dollar value, and a double for the Percent value. Because the line can only be a dollar or value and not both, one of the doubles will always be null. I get the feeling (but I may be wrong) that they way they did their setup isn't the best. I will probably implement a Rate class that contains an enum and a double, which should work, but if there is a 'better' way to do this, I would prefer to learn about that type of implementation.

        B 1 Reply Last reply
        0
        • L Lost User

          A quick and dirty solution;

          public class Rate
          {
          public double Value; // Holds either the dollar or percentage value

          public override string ToString ()
          {
          	string typeName = GetType().Name;
          	// removes the prefix, if present
          	if (typeName.StartsWith(typeof(Rate).Name))
          		typeName = typeName.Substring(typeof(Rate).Name.Length);
          	return typeName;
          }
          

          }
          // Console.WriteLine(myTransactionLine.Amount);
          // would then result in "Dollar" as output

          It'd be cleaner to introduce a new property than to abuse the ToString-method. Putting an enum in there that returns "Dollar" or "%" would require the base-class to have knowledge thereof. ..unless you introduce an abstract property that returns an object. Yes, that introduces an extra cast in the calling code, but that could easily be wrapped in a utility-method.

          Bastard Programmer from Hell :suss: if you can't read my code, try converting it here[^]

          H Offline
          H Offline
          hpjchobbes
          wrote on last edited by
          #7

          Thanks for the code! That would work as a temporary solution, I think! It's sounding like I should really start looking into abstract classes/properties for this type of need! I haven't gotten that far yet in my learning, but it's going to be my next topic for sure!

          L 1 Reply Last reply
          0
          • H hpjchobbes

            I'm still new, so I don't know if this is the best way to do what I am needing, and would like some feedback/advice. I have a class that contains a double value. This double could represent a dollar value or it could represent a percentage value. Only one or the other, it will never have both. At runtime, I will need to be able to tell what type of value this is. Here is what I came up with, which appears to work, but if there is a better way, I would prefer that.

            public class Rate
            {
            public double Value; // Holds either the dollar or percentage value
            }
            public class RateDollar : Rate {}
            public class RatePercentage : Rate {}

            public class TransactionLine
            {
            // There's more stuff here, but it's not relevant to show
            public Rate Amount;
            }

            // Set the rate amount to be a dollar
            myTransactionLine.Amount = new RateDollar();

            // I can check the type if needed
            if(myTransactionLine.Amount.GetType() == typeof(RateDollar)) // We have a dollar value
            if(myTransactionLine.Amount.GetType() == typeof(RatePercent)) // We have a percentage value

            For some reason, this seems like it is a clunky workaround. It also seems like it's possible for someone to create the value that is neither a RateDollar or RatePercent, and just as a plain Rate. Is there some way to prevent this, or is there a better way to accomplish what I am trying to do?

            P Offline
            P Offline
            PIEBALDconsult
            wrote on last edited by
            #8

            I'd make Rate abstract and maybe make it a struct or replace the field with a read-only property.

            hpjchobbes wrote:

            if(myTransactionLine.Amount.GetType() == typeof(RateDollar))

            if(myTransactionLine.Amount is RateDollar

            1 Reply Last reply
            0
            • H hpjchobbes

              Thanks for the code! That would work as a temporary solution, I think! It's sounding like I should really start looking into abstract classes/properties for this type of need! I haven't gotten that far yet in my learning, but it's going to be my next topic for sure!

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #9

              hpjchobbes wrote:

              Thanks for the code! That would work as a temporary solution, I think!

              You're welcome. PIEBald has an even neater solution btw :-D

              Bastard Programmer from Hell :suss: if you can't read my code, try converting it here[^]

              1 Reply Last reply
              0
              • L Lost User

                Use an interface rather than a class. It seems to make more sense I think Note: you could also use an abstract class... But I would go with the interface as you do not actually need logic at the base level...

                public interface IRate
                {
                double Value { get; set;}
                }

                public class RateDollar : IRate
                {
                public double Value { get; set;}
                }
                public class RatePercentage : IRate
                {
                public double Value { get; set;}
                }

                The thing I find odd is why are you doing a type check? If you are doing type checks this is often a red flag of 2 objects that really should not have a direct relation (sometimes). If you provide more detail I am sure someone can give some more advice. But as it stands I would say just use an interface.

                Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                S Offline
                S Offline
                SledgeHammer01
                wrote on last edited by
                #10

                Definitely would not use an interface here. Whats the point? Not everything needs to be an interface. Having 3 classes (or interfaces or whatever) just to hold a double is over engineering at its finest :).

                L 1 Reply Last reply
                0
                • H hpjchobbes

                  I'm still new, so I don't know if this is the best way to do what I am needing, and would like some feedback/advice. I have a class that contains a double value. This double could represent a dollar value or it could represent a percentage value. Only one or the other, it will never have both. At runtime, I will need to be able to tell what type of value this is. Here is what I came up with, which appears to work, but if there is a better way, I would prefer that.

                  public class Rate
                  {
                  public double Value; // Holds either the dollar or percentage value
                  }
                  public class RateDollar : Rate {}
                  public class RatePercentage : Rate {}

                  public class TransactionLine
                  {
                  // There's more stuff here, but it's not relevant to show
                  public Rate Amount;
                  }

                  // Set the rate amount to be a dollar
                  myTransactionLine.Amount = new RateDollar();

                  // I can check the type if needed
                  if(myTransactionLine.Amount.GetType() == typeof(RateDollar)) // We have a dollar value
                  if(myTransactionLine.Amount.GetType() == typeof(RatePercent)) // We have a percentage value

                  For some reason, this seems like it is a clunky workaround. It also seems like it's possible for someone to create the value that is neither a RateDollar or RatePercent, and just as a plain Rate. Is there some way to prevent this, or is there a better way to accomplish what I am trying to do?

                  S Offline
                  S Offline
                  SledgeHammer01
                  wrote on last edited by
                  #11

                  Lots of the responses here seem to be WAY over thinking things. 3 classes to hold a double value? Really? It doesn't seem like there is going to be any code in any of those 3 classes, so it should just be a single class with an enum indicating what it is. You aren't going to get around type checking all over the place. If you give us more info on what you are actually doing with the rates, we could provide more help. If its just for formatting, well, you would still have a single class and just override the ToString() that switches on the enum and formats with a % or $. And actually, the $ version should use the system formatter which formats currency according to the local settings.

                  J L 2 Replies Last reply
                  0
                  • S SledgeHammer01

                    Lots of the responses here seem to be WAY over thinking things. 3 classes to hold a double value? Really? It doesn't seem like there is going to be any code in any of those 3 classes, so it should just be a single class with an enum indicating what it is. You aren't going to get around type checking all over the place. If you give us more info on what you are actually doing with the rates, we could provide more help. If its just for formatting, well, you would still have a single class and just override the ToString() that switches on the enum and formats with a % or $. And actually, the $ version should use the system formatter which formats currency according to the local settings.

                    J Offline
                    J Offline
                    jschell
                    wrote on last edited by
                    #12

                    SledgeHammer01 wrote:

                    so it should just be a single class with an enum

                    A boolean would be sufficient.

                    S P 2 Replies Last reply
                    0
                    • J jschell

                      SledgeHammer01 wrote:

                      so it should just be a single class with an enum

                      A boolean would be sufficient.

                      S Offline
                      S Offline
                      SledgeHammer01
                      wrote on last edited by
                      #13

                      jschell wrote:

                      A boolean would be sufficient.

                      Sure, if you know that you'll never add a 3rd type.

                      1 Reply Last reply
                      0
                      • S SledgeHammer01

                        Definitely would not use an interface here. Whats the point? Not everything needs to be an interface. Having 3 classes (or interfaces or whatever) just to hold a double is over engineering at its finest :).

                        L Offline
                        L Offline
                        Lost User
                        wrote on last edited by
                        #14

                        SledgeHammer01 wrote:

                        Definitely would not use an interface here. Whats the point?

                        Because he has not stated his reason for layers but is trying to use it. That is the point.

                        SledgeHammer01 wrote:

                        Having 3 classes (or interfaces or whatever) just to hold a double is over engineering at its finest

                        I have seen cases where an empty interface is even used. It is not over engineering. It is creating a base API. By what the OP was an interface is exactly what should be used.

                        Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                        S 1 Reply Last reply
                        0
                        • S SledgeHammer01

                          Lots of the responses here seem to be WAY over thinking things. 3 classes to hold a double value? Really? It doesn't seem like there is going to be any code in any of those 3 classes, so it should just be a single class with an enum indicating what it is. You aren't going to get around type checking all over the place. If you give us more info on what you are actually doing with the rates, we could provide more help. If its just for formatting, well, you would still have a single class and just override the ToString() that switches on the enum and formats with a % or $. And actually, the $ version should use the system formatter which formats currency according to the local settings.

                          L Offline
                          L Offline
                          Lost User
                          wrote on last edited by
                          #15

                          Disappointing response. The responses are not over thinking. They are using what the OP posted and trying to provide an answer.

                          Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                          S 1 Reply Last reply
                          0
                          • L Lost User

                            SledgeHammer01 wrote:

                            Definitely would not use an interface here. Whats the point?

                            Because he has not stated his reason for layers but is trying to use it. That is the point.

                            SledgeHammer01 wrote:

                            Having 3 classes (or interfaces or whatever) just to hold a double is over engineering at its finest

                            I have seen cases where an empty interface is even used. It is not over engineering. It is creating a base API. By what the OP was an interface is exactly what should be used.

                            Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                            S Offline
                            S Offline
                            SledgeHammer01
                            wrote on last edited by
                            #16

                            Collin Jasnoch wrote:

                            Because he has not stated his reason for layers but is trying to use it. That is the point.

                            He did. He wanted to be able to tell the difference between a % and a $ amount. In which case an enum (or even a bool would suffice).

                            Collin Jasnoch wrote:

                            I have seen cases where an empty interface is even used. It is not over engineering. It is creating a base API.

                            By what the OP was an interface is exactly what should be used.

                            OP wanted to have a single double that held 2 different types of values and wanted to know a way to tell the difference between them. Using his GetType() solution required having 3 classes. The enum solution requires an enum & a single class. I'm not against interfaces, I use them all the time. I don't do stuff just cuz I can, I do stuff when its appropriate. I could also wear a tuxedo to go to Burger King, but I don't cuz that's slightly overkill :).

                            L 1 Reply Last reply
                            0
                            • L Lost User

                              Disappointing response. The responses are not over thinking. They are using what the OP posted and trying to provide an answer.

                              Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                              S Offline
                              S Offline
                              SledgeHammer01
                              wrote on last edited by
                              #17

                              OP already explained what he wanted:

                              Quote:

                              I have a class that contains a double value. This double could represent a dollar value or it could represent a percentage value. Only one or the other, it will never have both. At runtime, I will need to be able to tell what type of value this is. Here is what I came up with, which appears to work, but if there is a better way, I would prefer that.

                              He wanted a class that holds a double value and a way to determine the type of data. He thought the GetType() solution was clunky.

                              L 1 Reply Last reply
                              0
                              • S SledgeHammer01

                                Collin Jasnoch wrote:

                                Because he has not stated his reason for layers but is trying to use it. That is the point.

                                He did. He wanted to be able to tell the difference between a % and a $ amount. In which case an enum (or even a bool would suffice).

                                Collin Jasnoch wrote:

                                I have seen cases where an empty interface is even used. It is not over engineering. It is creating a base API.

                                By what the OP was an interface is exactly what should be used.

                                OP wanted to have a single double that held 2 different types of values and wanted to know a way to tell the difference between them. Using his GetType() solution required having 3 classes. The enum solution requires an enum & a single class. I'm not against interfaces, I use them all the time. I don't do stuff just cuz I can, I do stuff when its appropriate. I could also wear a tuxedo to go to Burger King, but I don't cuz that's slightly overkill :).

                                L Offline
                                L Offline
                                Lost User
                                wrote on last edited by
                                #18

                                I worked from what he had. He "HAD" the layer set up. If you re-read what I post you "SHOULD" notice I question his usage of layers. He did respond and now you have the leisure to provide condescending remarks with 20/20. Good for you.

                                Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                                1 Reply Last reply
                                0
                                • S SledgeHammer01

                                  OP already explained what he wanted:

                                  Quote:

                                  I have a class that contains a double value. This double could represent a dollar value or it could represent a percentage value. Only one or the other, it will never have both. At runtime, I will need to be able to tell what type of value this is. Here is what I came up with, which appears to work, but if there is a better way, I would prefer that.

                                  He wanted a class that holds a double value and a way to determine the type of data. He thought the GetType() solution was clunky.

                                  L Offline
                                  L Offline
                                  Lost User
                                  wrote on last edited by
                                  #19

                                  That is not exactly what his post states. Reading his other posts one can elude that.

                                  Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                                  J 1 Reply Last reply
                                  0
                                  • H hpjchobbes

                                    I'm still new, so I don't know if this is the best way to do what I am needing, and would like some feedback/advice. I have a class that contains a double value. This double could represent a dollar value or it could represent a percentage value. Only one or the other, it will never have both. At runtime, I will need to be able to tell what type of value this is. Here is what I came up with, which appears to work, but if there is a better way, I would prefer that.

                                    public class Rate
                                    {
                                    public double Value; // Holds either the dollar or percentage value
                                    }
                                    public class RateDollar : Rate {}
                                    public class RatePercentage : Rate {}

                                    public class TransactionLine
                                    {
                                    // There's more stuff here, but it's not relevant to show
                                    public Rate Amount;
                                    }

                                    // Set the rate amount to be a dollar
                                    myTransactionLine.Amount = new RateDollar();

                                    // I can check the type if needed
                                    if(myTransactionLine.Amount.GetType() == typeof(RateDollar)) // We have a dollar value
                                    if(myTransactionLine.Amount.GetType() == typeof(RatePercent)) // We have a percentage value

                                    For some reason, this seems like it is a clunky workaround. It also seems like it's possible for someone to create the value that is neither a RateDollar or RatePercent, and just as a plain Rate. Is there some way to prevent this, or is there a better way to accomplish what I am trying to do?

                                    T Offline
                                    T Offline
                                    Trak4Net
                                    wrote on last edited by
                                    #20

                                    I would be more inclined to use the enum over abstract classes and interface for something like this. Unless there is a deeper level of programming that isn't being shown I would stick with simplicity. This would be my interpetation of the object you are wanting also with a nice ToRateString() method so you can use the rate object to easily display your value in preformatted string.

                                    Rate r = new Rate(ENRateType.Dollar, 5.58d);
                                    //r.ToRateString() would display $5.58

                                       public enum ENRateType { Dollar, Percent }
                                    
                                       public class Rate
                                       {
                                           public Rate()
                                           {
                                               RateType = ENRateType.Dollar;
                                               Value = 0d;
                                           }
                                    
                                           public Rate(ENRateType rateType, double value) : this()
                                           {
                                               RateType = rateType;
                                               Value = value;
                                           }
                                    
                                           public ENRateType RateType {get; internal set;}
                                           public double Value { get; internal set; }
                                    
                                           public string ToRateString()
                                           {
                                               if (RateType == ENRateType.Dollar) return "$" + Value.ToString("0.00");
                                               return Value.ToString("0.000") + "%";
                                           }
                                    
                                       }
                                    
                                    P 1 Reply Last reply
                                    0
                                    • L Lost User

                                      That is not exactly what his post states. Reading his other posts one can elude that.

                                      Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.

                                      J Offline
                                      J Offline
                                      jschell
                                      wrote on last edited by
                                      #21

                                      Collin Jasnoch wrote:

                                      That is not exactly what his post states

                                      Looks to me that that is exactly what the OP said.

                                      1 Reply Last reply
                                      0
                                      • J jschell

                                        SledgeHammer01 wrote:

                                        so it should just be a single class with an enum

                                        A boolean would be sufficient.

                                        P Offline
                                        P Offline
                                        Paul Conrad
                                        wrote on last edited by
                                        #22

                                        I agree that a boolean would work fine, but an enumeration would be a lot easier to read. What if by some chance he has his requirements change and needs to keep track of more than two types for the value? This whole thing could go to hell really quick then. Seems like a lot of over engineering going on here :)

                                        "The clue train passed his station without stopping." - John Simmons / outlaw programmer

                                        1 Reply Last reply
                                        0
                                        • T Trak4Net

                                          I would be more inclined to use the enum over abstract classes and interface for something like this. Unless there is a deeper level of programming that isn't being shown I would stick with simplicity. This would be my interpetation of the object you are wanting also with a nice ToRateString() method so you can use the rate object to easily display your value in preformatted string.

                                          Rate r = new Rate(ENRateType.Dollar, 5.58d);
                                          //r.ToRateString() would display $5.58

                                             public enum ENRateType { Dollar, Percent }
                                          
                                             public class Rate
                                             {
                                                 public Rate()
                                                 {
                                                     RateType = ENRateType.Dollar;
                                                     Value = 0d;
                                                 }
                                          
                                                 public Rate(ENRateType rateType, double value) : this()
                                                 {
                                                     RateType = rateType;
                                                     Value = value;
                                                 }
                                          
                                                 public ENRateType RateType {get; internal set;}
                                                 public double Value { get; internal set; }
                                          
                                                 public string ToRateString()
                                                 {
                                                     if (RateType == ENRateType.Dollar) return "$" + Value.ToString("0.00");
                                                     return Value.ToString("0.000") + "%";
                                                 }
                                          
                                             }
                                          
                                          P Offline
                                          P Offline
                                          Paul Conrad
                                          wrote on last edited by
                                          #23

                                          Trak4Net wrote:

                                          stick with simplicity

                                          Same here. At least try to keep things as simple as possible.

                                          "The clue train passed his station without stopping." - John Simmons / outlaw programmer

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups