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.
  • 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
                            • 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?

                              N Offline
                              N Offline
                              Northcodedotno
                              wrote on last edited by
                              #24

                              From what I see there are several ways to do this: 1. Use class/interface inheritance 2. Use an enum 3. Use a boolean It all depends on what you want, If you want good control over the different types of rates you should use class/interface inheritance, if the dollar rate should have different functionality than say a euro rate (convert between rates etc...) Example:

                              interface Rate
                              {
                              double getValue();
                              }

                              class DollarRate : Rate
                              {
                              double rawval; //the actual value

                              internal double getValue()
                              {
                                  return rawval \* 6; //format in the way you want
                              }
                              

                              }

                              class PercetageRate : Rate
                              {
                              double rawval; //again, the value

                              internal double getValue()
                              {
                                  return rawval; //I just use the raw value for percentage
                              }
                              

                              }

                              class EuroRate : Rate
                              {
                              double rawval;

                              internal double getValue()
                              {
                                  return rawval \* 9; //some other rate
                              }
                              

                              }

                              void Main()
                              {
                              if(myTransactionLine.Amount is DollarRate)
                              {
                              //do dollar
                              }
                              else if(myTransactionLine.Amount is PercetageRate)
                              {
                              //do percentage
                              }
                              //continue...
                              }

                              If you don't need this then just use the enum approach to save time and space. I also came up with my own approach, I think it's the fastest one that allows for more than 2 rates (IE the bool method) It works like the enum approach but instead of enums you use constants. (It's faster because constants are converted to a raw value at compile time) Example:

                              static class Rates
                              {
                              //you can use whatever datatype you want, I choose byte since its 4 times smaller than int and can hold 256 cominations (including 0). You could also use chars: DOLLAR = '$', PERCENTAGE = '%', EURO = '€' etc...
                              public const byte DOLLAR = 0;
                              public const byte PERCENTAGE = 1;
                              public const byte EURO = 2;
                              //add more constants for more rates
                              }

                              class Rate
                              {
                              double value;
                              byte type; //the type of the rate

                              internal double Value
                              {
                                  get { return value; }
                              }
                              
                              internal byte Type
                              {
                                  get { return type; }
                              }
                              

                              }

                              void Main()
                              {
                              if(myTransactionLine.Amount.Type == Rates.DOLLAR)
                              {
                              //do dollar
                              }
                              else if(myTransactionLine.Amount is Rates.PERCENTAGE)
                              {
                              //do percentage
                              }
                              //continue...
                              }

                              Hope this helps! Sorry for long post...

                              1 Reply Last reply
                              0
                              • H hpjchobbes

                                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 Offline
                                B Offline
                                BillWoodruff
                                wrote on last edited by
                                #25

                                To me this information indicates you are "free" to change the Rate class in the program you get the information from: is that correct ? The use of the phrases "They have," and "they did," and, "I am interacting with another software," is what gives me the idea you may not have freedom to change the Rate class. thanks, Bill

                                "Everything we call real is made of things that cannot be regarded as real." Niels Bohr

                                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?

                                  B Offline
                                  B Offline
                                  BobJanova
                                  wrote on last edited by
                                  #26

                                  As is often the case with newish people, I don't think you've actually asked the right question. What's your real requirement here? From reading the thread, it appears to be that you want a surcharge, either a percentage or a fixed amount, to be applied to a bill. What's the interface to that?

                                  interface ISurcharge {
                                  double GetAmount(Order order);
                                  string Name { get; }
                                  }

                                  ... or, if it's just on the amount, you can pass a number instead of an order. My guess, though, is different tax rates may apply to different items so you will eventually need to pass the order. Note the important thing here: the value of the surcharge depends (in general) on the existing order so it needs to be part of the interface. The Name property is for what gets displayed on the bill; you may want a few other little things like that, but this is the core functionality. Now you can create trivial implementation classes to solve the problem!

                                  class FixedSurcharge : ISurcharge {
                                  private double amount;
                                  public string Name { get; private set; }
                                  public FixedSurcharge(string name, double amount) { Name = name; this.amount = amount; }
                                  public double GetAmount(Order order) { return amount; }
                                  }

                                  class PercentageSurcharge : ISurcharge {
                                  private double percentage;
                                  public string Name { get; private set; }
                                  public PercentageSurcharge (string name, double percentage) { Name = name; this.percentage = percentage; }
                                  public double GetAmount(Order order) { return percentage * 0.01 * order.TotalValue; }
                                  }

                                  ... called like:

                                  void placeOrder(Order order){
                                  foreach(OrderItem item in order.Items) { addBillItem(item.Name, item.Value); }
                                  addSurcharge(new PercentageSurcharge("VAT", 20), order);
                                  addSurcharge(new FixedSurcharge("Shipping", 2.50), order);
                                  }

                                  void addSurcharge(ISurcharge surcharge, Order order){
                                  addBillItem(surcharge.Name, surcharge.GetAmount(order));
                                  }

                                  (Actually, on reflection it may be cleaner to make fake order items, with a Value property, by passing the existing Order to a constructor and stashing it in the Surcharge instance. That's a matter of style, I think.)

                                  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