Author Topic: C# question  (Read 2651 times)

0 Members and 1 Guest are viewing this topic.

Offline DavidDLCTopic starter

  • Frequent Contributor
  • **
  • Posts: 755
  • Country: us
C# question
« on: August 08, 2018, 06:09:49 am »
I want to make a Fluke287Class, then I want to create an object from this class named Fluke287:
Fluke287Class Fluke287 = new Fluke287Class();

Then I want to have:

Fluke287.Configure.Range(Some value) or
Fluke287.Measure.Voltage()

How can I achieve this ? I cannot do it with nested classes, because I want to create the object from the class and not a static class.

David DLC
 

Offline rjp

  • Regular Contributor
  • *
  • Posts: 124
  • Country: au
Re: C# question
« Reply #1 on: August 08, 2018, 09:00:28 am »
you would make the sub object public and then create them inside the toplevel class constructor.
Code: [Select]
class TheSub {}

class TheTop {

  public TheSub Sub { get; protected set; }

  public TheTop()
  {
  Sub  = new TheSub();
   }

}
 

Offline Ash

  • Regular Contributor
  • *
  • Posts: 161
  • Country: au
Re: C# question
« Reply #2 on: August 08, 2018, 09:50:19 am »
Fluke287.Configure.Range(Some value) or
Fluke287.Measure.Voltage()

Hi David,

You can certainly warp the C# to achieve this, similar to what rjp suggested.. (though I'd make the Sub classes private and inside the outer class) but really the question is why?

This is a very uncommon way to do this. The problem is that I assume you will have some sort of connection that all the sub object then need to share.. And how do you deal with conflicting setup? IE set an invalid range then try to measure something?

What's wrong with:

Code: [Select]

enum VoltageRange
{
    Millivolts_100,
    Volts_1,
    Volts_10,
// etc
}

enum CurrentRange
{
    Milliamps_100,
    Amps_1,
    Amps_10,
// etc
}


class Fluke287
{
    public Fluke287(/*some connection settings here*/) {...}

    public double MeasureVoltage(VoltageRange range) {...}
    public double MeasureCurrent(CurrentRange range) {...}
}

var fluke287 = new Fluke287(/*some connection settings*/);

fluke287.MeasureVoltage(VoltageRange.Volts_10);
fluke287.MeasureCurrent(CurrentRange.Milliamps_100);



Then everything is available at the sample place and time.. The range can be set (if not already correct, assuming you track it in the object) and then the measurement take. The enums restrict the valid range of settings (and are different for voltage and current)..

[EDIT: Sorry, I accidentally posted before I finished writing]


« Last Edit: August 08, 2018, 09:54:03 am by Ash »
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23018
  • Country: gb
Re: C# question
« Reply #3 on: August 08, 2018, 09:52:10 am »
I wouldn't heavily namespace like that to be honest unless you're going to program via interfaces for different devices.

Here's how I'd do this as a one off:

Code: [Select]
var fluke = new Fluke289();
fluke.SetFunction(Fluke289Function.Voltage);
fluke.SetRange(Fluke289Range.mV100);
var result = fluke.Measure();

Nothing at all happens other than mutating private variables until you call Measure();

I wouldn't have separate measurement methods for each type unless you are using derived types which isn't worth it as what you're returning is a double usually regardless of the range.

Edit: to note you probably can't SetFunction unless you have a bench DMM with total software control of functions. Twirly knob DMM this is pointless. Better to write a thin layer over the SCPI interface if you can just to add type safety to the meter's programming interface.
« Last Edit: August 08, 2018, 09:57:57 am by bd139 »
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11790
  • Country: us
Re: C# question
« Reply #4 on: August 08, 2018, 09:52:22 am »
I want to make a Fluke287Class, then I want to create an object from this class named Fluke287:
Fluke287Class Fluke287 = new Fluke287Class();

Just FYI, this isn't really a natural way to code this. There is no need to call a class "Fluke287Class" because it is already known to be a class. The word "Class" in the name is redundant. So a more canonical way to do it would be like this:

Code: [Select]
var meter = new Fluke287();
The reason for calling the reference "meter" is that you might at some point wish to have a base class or interface that represents DMMs in general. Then the Fluke287 class would be a specialization that represents that specific meter. In future you might also have a version for the Brymen 869s, in which case you might then write:

Code: [Select]
var meter = new Brymen869();
Everything about "meter" would work just the same whichever kind of meter it happened to be, which would save you re-writing your program for different meters. You would just implement a new meter class for each kind of meter you wish to support.
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23018
  • Country: gb
Re: C# question
« Reply #5 on: August 08, 2018, 09:55:08 am »
Honestly it's not worth building a generic interface for this unless you're shipping a product. It's a difficult thing to do. Seriously. I have done it :)

You then start the following list of questions:

1. What if different meters have different communciation protocols
2. How do you handle range differences between meters.
3. How do you handle dual measurements
4. How do you handle meters which can set range and some that can't.
5. How do you handle probe alert.
6. How do you handle triggered/sync reads versus sampling measurements.
7. How do you handle interface lock out and synchronising state of the meter with the software (if someone hits a button)
8. Numerous other annoying concerns.
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11790
  • Country: us
Re: C# question
« Reply #6 on: August 08, 2018, 11:44:31 am »
Honestly it's not worth building a generic interface for this unless you're shipping a product. It's a difficult thing to do. Seriously. I have done it :)

You then start the following list of questions:

1. What if different meters have different communciation protocols
2. How do you handle range differences between meters.
3. How do you handle dual measurements
4. How do you handle meters which can set range and some that can't.
5. How do you handle probe alert.
6. How do you handle triggered/sync reads versus sampling measurements.
7. How do you handle interface lock out and synchronising state of the meter with the software (if someone hits a button)
8. Numerous other annoying concerns.

Your list of questions is very valid. You would not go to the trouble of creating a generic interface for the first meter. However, once you have implemented a second and a third, you will start to see common or repeated code, at which point you will likely want to factor that out into a shared base class. And from there a generic interface becomes a logical step.
 

Offline DavidDLCTopic starter

  • Frequent Contributor
  • **
  • Posts: 755
  • Country: us
Re: C# question
« Reply #7 on: August 08, 2018, 05:11:05 pm »
I want to make a Fluke287Class, then I want to create an object from this class named Fluke287:
Fluke287Class Fluke287 = new Fluke287Class();

This was just for better understanding of what I want to achieve.

David DLC
 

Offline DavidDLCTopic starter

  • Frequent Contributor
  • **
  • Posts: 755
  • Country: us
Re: C# question
« Reply #8 on: August 08, 2018, 05:27:35 pm »

Edit: to note you probably can't SetFunction unless you have a bench DMM with total software control of functions. Twirly knob DMM this is pointless. Better to write a thin layer over the SCPI interface if you can just to add type safety to the meter's programming interface.

I know that, I took the wrong model to ask for my original question.
 

Offline DavidDLCTopic starter

  • Frequent Contributor
  • **
  • Posts: 755
  • Country: us
Re: C# question
« Reply #9 on: August 08, 2018, 05:37:16 pm »
I want to have:

Fluke287.Measure.Voltage() <-- This directly indicates me I want to measure voltage
Fluke287.Measure() <-- This does not indicate me what I want to measure

Fluke287.Measure("Voltage") <-- I rather like Fluke287.Measure.Voltage()

David DLC
 

Offline Wilksey

  • Super Contributor
  • ***
  • Posts: 1329
Re: C# question
« Reply #10 on: August 08, 2018, 08:57:01 pm »
Project namespace would be Fluke287, class namespace would be Measure, function would be Voltage()

Am I missing something?
 

Offline rjp

  • Regular Contributor
  • *
  • Posts: 124
  • Country: au
Re: C# question
« Reply #11 on: August 09, 2018, 01:20:28 am »
personally i would do.

Code: [Select]
public abstract class DMM
{
     abstract public double MeasureVoltage();
}

public class Fluke287 : DMM
{
     public override double MeasureVoltage() { return blah; }
}



that is clear and extendable.
 

Offline Ash

  • Regular Contributor
  • *
  • Posts: 161
  • Country: au
Re: C# question
« Reply #12 on: August 09, 2018, 02:09:38 am »
I want to have:

Fluke287.Measure.Voltage() <-- This directly indicates me I want to measure voltage
Fluke287.Measure() <-- This does not indicate me what I want to measure

Fluke287.Measure("Voltage") <-- I rather like Fluke287.Measure.Voltage()


what is wrong with:

Code: [Select]
fluke287.MeasureVoltate();
fluke287.MeasureCurrent();
//etc

Same distinction, different method names, and without the nested object headache.

Ash.
 

Offline DavidDLCTopic starter

  • Frequent Contributor
  • **
  • Posts: 755
  • Country: us
Re: C# question
« Reply #13 on: August 14, 2018, 02:00:02 am »
NET Framework has a lot of nesting on itself, these are just some examples of many they have:

System.IO.IsolatedStorage.IsolatedStorageFileStream
System.IO.Directory


So why people say having

Fluke287.Measure.Current
Fluke287.Measure.Voltage

Is not a good way of programming this.

I thought it was possible to have a class Measure and with the voltage, current and other methods on it

David DLC
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11790
  • Country: us
Re: C# question
« Reply #14 on: August 14, 2018, 06:23:01 am »
NET Framework has a lot of nesting on itself, these are just some examples of many they have:

System.IO.IsolatedStorage.IsolatedStorageFileStream
System.IO.Directory

These are namespaces for organizing things. A bit like "Floor 2, aisle 3, 3rd shelf down" in a library.

Quote
So why people say having

Fluke287.Measure.Current
Fluke287.Measure.Voltage

Is not a good way of programming this.

Because what you are writing here is something different and doesn't seem to make a lot of sense.

Quote
I thought it was possible to have a class Measure and with the voltage, current and other methods on it.

Everything is possible. Not everything is sensible.

You still haven't answered what "Measure current" is supposed to do if the meter has a voltage range selected?
 

Offline Tony_G

  • Frequent Contributor
  • **
  • Posts: 899
  • Country: us
  • Checkout my old test gear channel (link in sig)
    • TGSoapbox
Re: C# question
« Reply #15 on: August 14, 2018, 04:09:46 pm »
You can see how it is implemented in the reference source. For example System.IO.Directory that DavidDLC mentioned is located here:

https://referencesource.microsoft.com/#mscorlib/system/io/directory.cs,b3ad5f0ba800bb28

And System.IO.IsolatedStorage.IsolatedStorageFileStream

https://referencesource.microsoft.com/#mscorlib/system/io/isolatedstorage/isolatedstoragefilestream.cs,3170da5a80264939

As IanB said, these are namespace conventions and not nested classes. All of this code should have been run through FxCop as a checkin gate so design & naming should be a reasonable point for copying design.

TonyG

Offline alexanderbrevig

  • Frequent Contributor
  • **
  • Posts: 700
  • Country: no
  • Musician, developer and EE hobbyist
    • alexanderbrevig.com
Re: C# question
« Reply #16 on: August 14, 2018, 05:10:31 pm »
It kind of looks like the Method Chaining pattern.
https://en.m.wikipedia.org/wiki/Method_chaining

If you want to nest classes then you could use dependency injection to f.ex configure the Measure instance according to which DMM you instantiate, maybe implementing different transport layers?

Do not new it in the constructor.  Either take an instance or have DI fetch one for you. :)
 

Offline DavidDLCTopic starter

  • Frequent Contributor
  • **
  • Posts: 755
  • Country: us
Re: C# question
« Reply #17 on: August 15, 2018, 05:41:17 am »


Quote
I thought it was possible to have a class Measure and with the voltage, current and other methods on it.

Everything is possible. Not everything is sensible.

You still haven't answered what "Measure current" is supposed to do if the meter has a voltage range selected?
[/quote]

Measure.Current will display a message saying the meter is not set for current measurement
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf