I have a abstact class Camera, Interface ICamera, LSM is inheritance with Camera, ICamera. LSM is pointed to CameraSettings. And private void button1_Click event is called when running this program.
I would like to fix "lack of the get accestor" problem when I run this. I just want write only property for the camera.
namespace
Hardware{
public class CameraSettings{
public
int iCameraGain; // Camera Gainpublic
CameraSettings( int iGain){iCameraGain = iGain;}
public int CameraGain
{
get { return iCameraGain;} set { iCameraGain = value; }}
namespace
Hardware{
//Abstract class for a cameras public abstract class Camera{
public abstract CameraSettings cameraSettings{
set;}}}
namespace
Hardware{
public interface ICamera{
CameraSettings cameraSettings { set;}}}
namespace
Hardware{
//Class for OptoMetrix Scan LSM-1002A public class LSM : Camera, ICamera{
public enum Gain { X1 = 0, X2 , X4 , X8 , X10 , X20 , X40 , X80 , X100 , X200 , X400 }; private CameraSettings MyCameraSettings; public override CameraSettings cameraSettings{
set { CameraSettings My_CameraSettings = new CameraSettings(1);My_CameraSettings.CameraGain = 0;
MyCameraSettings = My_CameraSettings;
if (value.CameraGain < 0 || value.CameraGain > 10) throw new ArgumentOutOfRangeException("Invalid setting!"); elseMyCameraSettings.CameraGain = cameraSettings.CameraGain;
}
}
And myTest:
private
void button1_Click(object sender, EventArgs e){
int Retval; LSM MyLSM = new LSM ();MyLSM.CameraGain = 1;
}

lack of the get accestor problem
xRuntime
That is correct. It wouldn't generate an exception in your original code either. The problem is that you are trying to validate the value of a member of the camera when you assign the camera to something else (LSM). This is normally not the way things are done. In fact you really can't do that easily anyway. If you want to do validation when the camera settings are changed AND the validation depends on the camera then I'd recommend that you create a custom class for each of the different camera settings (which ultimately would do the validation anyway). To keep things in control you'd then want to ensure that each camera sets up its own settings and doesn't allow users to change the settings class. Here is an updated version of your code.
public interface ICamera
{
CameraSettings CameraSettings { get; }
}
public abstract class Camera : ICamera
{
private CameraSettings m_Settings = new CameraSettings();
public CameraSettings CameraSettings
{
get { return m_Settings; }
protected set { m_Settings = value; }
}
}
public class CameraSettings
{
private int m_nGain;
public int Gain
{
get { return m_nGain; }
set { SetGain(value); }
}
protected virtual void SetGain ( int value )
{
m_nGain = value;
}
}
internal class LSMCameraSettings : CameraSettings
{
protected override void SetGain ( int value )
{
//Validate
base.SetGain(value);
}
}
public class LSM : Camera
{
//Initialize the camera settings
public LSM ( )
{
CameraSettings = new LSMCameraSettings();
}
}
Just to keep things consistent I left the interface and abstract base class for camera as it is a good design pattern to follow. What happens with the rest of the code is that each camera class can (but doesn't have to) define a custom camera settings class and assign it to the camera (through a protected setter). If there is never a case where a generic camera setting class can be used then make the base camera settings class abstract. Now you'll get the behavior you want because the validation is occuring on the object that you are attempting to set rather than a parent.
Michael Taylor - 11/15/06
ar_pad
I don't understand the "lack of get accestor" problem that you are referring to. Do you want to have a get accessor in LSM If so then just define one. However the problem would come in that Camera does not expose a getter. You should also update Camera to have a getter. Additionally you might want to consider exposing a getter from ICamera as well.
Looking at your code I'm guessing that you have an ICamera interface that you want to expose and you want to provide a base implementation through Camera. You will provide a concrete implementation through LSM. In this case your implementation isn't quite as clean as it could be. Here's how I'd rework it for maximum flexibility.
public interface ICamera
{
CameraSettings CameraSettings { get; set; }
}
public abstract class Camera : ICamera
{
private CameraSettings m_Settings = new CameraSettings();
public CameraSettings CameraSettings
{
get { return m_Settings; }
set { SetCameraSettings(value); }
}
protected virtual void SetCameraSettings ( CameraSettings value )
{
m_Settings = value;
}
}
public class LSM : Camera
{
//Override any non-default behavior
protected override void SetCameraSettings ( CameraSettings value )
{
if (value.Gain is not valid)
throw an exception
base.SetCameraSettings(value);
}
}
Note that you should really never have a case where you have a setter but not a getter. Probably the only time this is remotely reasonable is when you have a password-style property. However even in that case you should define the getter and simply return a generic value.
The above code allows users to completely define a camera by implementing ICamera or using the base implementation provided in Camera. They can override the implementation as needed. However in this case there shouldn't be any. Note that I'm not a fan of virtual properties because they slow all calls down just for limited cases where you want to override the implementation. Therefore you see that the settings property is not virtual but it calls a virtual method to set the value.
Michael Taylor - 11/15/06
Izzy545
Michael Taylor - 11/15/06
Yogesh Shah
Thanks Michaels. It helps a lot.
Since it wouldn't generate an exception in your original code so that I try to take out the get property and just write only property.
I though it has easier way than I have to generate the custom class for each camera settings since we will have upto 20 cameras in the system.
I am learning C# as well as coding so it's kinda slow.
Thanks always,
Tammy
Roberto Sartori
MyCameraSettings.CameraGain = cameraSettings.CameraGain;
You probably meant to write:
MyCameraSettings.CameraGain = value.CameraGain;
Your test code doesn't compile either, the LSM class doesn't have a CameraGain property.
LSM MyLSM = new LSM();
CameraSettings settings = new CameraSettings(1);
MyLSM.cameraSettings = settings;
You need to rethink this code, it is on the left side of readable.
Matt Bell
Hi Michael,
Thanks for your inputs. However, when I run myTest, which set: myLSM.CameraSettings.Camera = 1, it doesn't go into protected override void CameraSettings function at all... So that, when I set cameragain as invalid number, it doesn't throw an exception.
Any other inputs Thanks so much,
Tammy