Trying to simplify the code - c#-4.0

Does anybody suggest me how can I simplify the follow code
private bool isMethodCalled;
private void CallMethod()
{
if (!isMethodCalled)
{
this.CallCertainMethod();
isMethodCalled = true;
}
}
private int field1;
public int Property1
{
get
{
CallMethod();
return this.field1;
}
set { this.field1 = value; }
}
private int field2;
public int Property2
{
get
{
CallMethod();
return this.field2;
}
set { this.field2 = value; }
}
private int field3;
public int Property3
{
get
{
CallMethod();
return this.field3;
}
set { this.field3 = value; }
}

You could use an AOP framework like PostSharp to create an attribute which would call CallMethod and just use automatic properties for Property1, Property2 and Property3. Although it wouldn't save much in the number of lines of code unless there are a lot of other properties.

Something you can simplify is the following:
private void CallMethod()
{
if (!isMethodCalled)
{
this.CallCertainMethod();
isMethodCalled = true;
}
}
to:
private void CallMethod()
{
if (!isMethodCalled) this.CallCertainMethod();
isMethodCalled = true;
}
As a side note:
I don't know what CallCertainMethod() does. Just in case, it is not recommended to query data and mutate state at the same time. See Command Query-Separation, which states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer.

Related

How to assign values to the class attributes in C#?

I'm new to C# programming and trying to write the following program using "Vihicle" interface properties that are inherited in 'Car', 'Truck' classes. The problem I'm facing is this error:
An unhandled exception of type 'System.StackOverflowException' occurred"
I get this while assigning the values to the Car properties. Here is my code:
namespace Inheritance_Assignment_2
{
interface Vihicle
{
string Make
{
get;
set;
}
String Model
{
get;
set;
}
int Year
{
get;
set;
}
void DisplayInfo();
float calculateMileage();
}
class Car : Vihicle
{
private string make;
public string Make // read-write instance property
{
get
{
return Make;
}
set
{
Make = value;
}
}
private string model;
public string Model // read-write instance property
{
get
{
return Model;
}
set
{
Model = value;
}
}
private int year;
public int Year // read-write instance property
{
get
{
return Year;
}
set
{
Year = value;
}
}
public void DisplayInfo()
{
Console.WriteLine(Make);
Console.WriteLine(Model);
Console.WriteLine(Year);
}
public float calculateMileage()
{
Random random = new Random();
float value = random.Next(10, 20);
return value;
}
}
class Truck : Vihicle
{
private string make;
public string Make // read-write instance property
{
get
{
return Make;
}
set
{
Make = value;
}
}
private string model;
public string Model // read-write instance property
{
get
{
return Model;
}
set
{
Model = value;
}
}
private int year;
public int Year // read-write instance property
{
get
{
return Year;
}
set
{
Year = value;
}
}
public void DisplayInfo()
{
Console.WriteLine(Make);
Console.WriteLine(Model);
Console.WriteLine(Year);
}
public float calculateMileage()
{
throw new NotImplementedException();
}
}
class TowingTruck : Truck
{
public string TowingCapacity // read-write instance property
{
get
{
return TowingCapacity;
}
set
{
TowingCapacity = value;
}
}
public void DisplayInfo() // Overrided function of class truck because this function doing some extra printing of
{ //TowingCapacity that is present in this TowingTruck Child of Truck Class
Console.WriteLine(Make);
Console.WriteLine(Model);
Console.WriteLine(Year);
Console.WriteLine(TowingCapacity);
}
public float calculateMileage()
{
throw new NotImplementedException();
}
}
class DeliveryTruck : Truck
{
public string Make // read-write instance property
{
get
{
return Make;
}
set
{
Make = value;
}
}
public string Model // read-write instance property
{
get
{
return Model;
}
set
{
Model = value;
}
}
public int Year // read-write instance property
{
get
{
return Year;
}
set
{
Year = value;
}
}
/*
public void DisplayInfo()
{
Console.WriteLine(Make);
Console.WriteLine(Model);
Console.WriteLine(Year);
}
public float calculateMileage()
{
// throw new NotImplementedException();
return 0;
}
*/
}
class Program
{
static void Main(string[] args)
{
//while (true) // Loop indefinitely
//{
// string name;
// int age;
// double height;
// Console.Write("Enter your name: ");
// name = Console.ReadLine();
// Console.Write("Enter your age: ");
// age = Convert.ToInt32(Console.ReadLine());
// Console.Write("Enter your height: ");
// height = Convert.ToDouble(Console.ReadLine());
// //Print a blank line
// Console.WriteLine();
// //Show the details you typed
// Console.WriteLine( name);
// Console.WriteLine( age);
// Console.WriteLine("Height is ", height);
// Console.WriteLine('\n');
//}
Car C = new Car();
float rnum = C.calculateMileage();
Console.WriteLine("Here is the Milage : " + rnum);
C.Make = System.Console.ReadLine();
System.Console.WriteLine("The employee information:");
System.Console.WriteLine("Employee name: {0}", C.Make);
//Console.Write("Enter your Model : ");
//C.Model = Console.ReadLine();
//Console.WriteLine(C.Model);
//Console.ReadLine();
}
}
}
Look at your properties:
private string make;
public string Make // read-write instance property
{
get
{
return Make;
}
set
{
Make = value;
}
}
When you read a value from Make, it internally reads a value from Make (same with writing a value), which results in an infinite recursion. You need to read/write from the variable which holds the value:
private string make;
public string Make // read-write instance property
{
get
{
return make;
}
set
{
make = value;
}
}
A property's internal logic can't reference itself. Something actually has to store the value.
Edit: Unless there's any particular reason to use properties like this (such as requiring more logic in the getters/setters), you can just use auto-generated properties to simplify the code. So instead of this:
private string make;
public string Make // read-write instance property
{
get
{
return make;
}
set
{
make = value;
}
}
You can just use this:
public string Make { get; set; }
The compiler automatically converts the latter into something very similar to the former (maybe with just a different backing variable name).

How to avoid Reload on property set

public bool ShowButton
{
get
{
return _ShowButton;
}
set
{
_ShowButton = value;
ReloadGrid();
}
}
public bool ShowText
{
get
{
return _ShowText;
}
set
{
_ShowText = value;
ReloadGrid();
}
}
private void ReloadGrid()
{
Gridview.Data ......
}
When ever am setting those two proprities i need to call ReloadGrid. But my requirement is if i assigned the 2 properties also ReloadGrid should call only one time now its happening twice. How to avoid this ?
How to avoid this ?
By not calling ReloadGrid in the setter of the properties.
public bool ShowButton { get; set; }
public bool ShowText { get; set; }
You have to call it manually:
ShowButton = true;
ShowText = false;
ReloadGrid();
The other option is more difficult. You need a bool variable to store if it's already loaded and you have to set it to false in events where the data needs to be refreshed. Then you can check this variable in ReloadGrid:
private bool GridNeedsReload { get; set; }
private void ReloadGrid()
{
if(GridNeedsReload)
{
Gridview.Data ......
}
}

How to specify the get/set internal var in a property in C#

Is there a way to specify the private field to store a public get value in? Or is that really pointless. Something like this:
private int _myint = 5;
public int MyInt { get(ref _myint); }
Obviously the current method is:
public in MyInt { get; private set; }
But that doesn't let you access the backing store. I don't know, maybe this doesn't even have a use case, but I thought I'd ask.
You'd just do a traditional property at that point:
private int _myInt;
public int MyInt { get { return _myInt; } }
// or
private int _myInt;
public int MyInt { get { return _myInt; } private set { _myInt = value; } }
The second one just means that you have a wrapper around your field which can be used inside of your class. Either way, your field can only be set from inside this class.
You just need to not use the automatic properties:
private int _myint = 5;
public int MyInt
{
get { return _myint; }
private set { _myint = value; }
}
The automatic properties just provide a shorter, more convenient syntax where the compiler creates and names the backing field for you.

BlackBerry - cancel a thread executed in another class to refresh location

How can I cancel a thread from another class fetching/refreshing location. I am able to cancel a thread from within the same class. But I am unable to do this across classes. Declaring the GPSThread static did not help. Can anyone please guide?
Class1:
public class GPSListener {
/* Other instantiation code */
Dialog busyDialog1 = new Dialog("Refreshing Location...",
new String [] { "Cancel" },
new int [] { Dialog.CANCEL},
Dialog.CANCEL,
Bitmap.getPredefinedBitmap(Bitmap.HOURGLASS))
{
public void fieldChanged(Field field1, int context1)
{
GPSHandler.requestStop();
busyDialog1.cancel();
}
};
public String refreshCoordinates() {
String test = "nothing";
if (GPSHandler.isStopRequested())
{
GPSHandler.stopRequested = false;
return null;
}
GPSHandler.getInstance().setListener(this);
GPSHandler.getInstance().requestLocationUpdates();
if (GPSHandler.isStopRequested())
{
GPSHandler.stopRequested = false;
return null;
}
busyDialog1.setEscapeEnabled(false);
busyDialog1.show();
return test;
}
public void onLocationReceived(Coordinates location) {
lblLatitude.setText(Double.toString(location.getLatitude()));
lblLongitude.setText(Double.toString(location.getLongitude()));
busyDialog1.cancel();
}
}
Class 2:
public class GPSHandler {
private GPSThread _gpsThread;
private Coordinates _location;
private boolean _gotLocation;
private GPSListener _listener;
/** this class will be a Singleton, as the device only has one GPS system */
private static GPSHandler _instance;
/** #return the Singleton instance of the GPSHandler */
public static GPSHandler getInstance() {
if (_instance == null) {
_instance = new GPSHandler();
}
return _instance;
}
public static boolean stopRequested = false;
public synchronized static void requestStop() {
stopRequested = true;
}
public synchronized static boolean isStopRequested() {
return stopRequested;
}
/** not publicly accessible ... use getInstance() */
private GPSHandler() {
}
/** call this to trigger a new location fix */
public void requestLocationUpdates() {
if (_gpsThread == null || !_gpsThread.isAlive()) {
_gpsThread = new GPSThread();
_gpsThread.start();
}
}
public void setListener(GPSListener listener) {
// only supports one listener this way
_listener = listener;
}
private void setLocation(final Coordinates value) {
_location = value;
if (value.getLatitude() != 0.0 || value.getLongitude() != 0.0) {
_gotLocation = true;
if (_listener != null) {
// this assumes listeners are UI listeners, and want callbacks on the UI thread:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_listener.onLocationReceived(value);
}
});
}
}
}
private class GPSThread extends Thread {
private void getLocationFromGoogle() {
try {
int cellID = GPRSInfo.getCellInfo().getCellId();
int lac = GPRSInfo.getCellInfo().getLAC();
String urlString2 = "http://www.google.com/glm/mmap";
// Open a connection to Google Maps API
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(urlString2);
HttpConnection httpConn2;
httpConn2 = (HttpConnection)connDesc.getConnection();
httpConn2.setRequestMethod("POST");
// Write some custom data to Google Maps API
OutputStream outputStream2 = httpConn2.openOutputStream();//getOutputStream();
writeDataGoogleMaps(outputStream2, cellID, lac);
// Get the response
InputStream inputStream2 = httpConn2.openInputStream();//getInputStream();
DataInputStream dataInputStream2 = new DataInputStream(inputStream2);
// Interpret the response obtained
dataInputStream2.readShort();
dataInputStream2.readByte();
final int code = dataInputStream2.readInt();
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(code + "");
}
});
if (code == 0) {
final double latitude = dataInputStream2.readInt() / 1000000D;
final double longitude = dataInputStream2.readInt() / 1000000D;
setLocation(new Coordinates(latitude, longitude, 0.0f));
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(latitude+"-----"+longitude);
}
});
dataInputStream2.readInt();
dataInputStream2.readInt();
dataInputStream2.readUTF();
} else {
System.out.println("Error obtaining Cell Id ");
}
outputStream2.close();
inputStream2.close();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
private void tryGetLocationFromDevice() {
_gotLocation = false;
try {
Criteria myCriteria = new Criteria();
myCriteria.setCostAllowed(false);
LocationProvider myLocationProvider = LocationProvider.getInstance(myCriteria);
try {
Location myLocation = myLocationProvider.getLocation(300);
setLocation(myLocation.getQualifiedCoordinates());
} catch ( InterruptedException iex ) {
System.out.println(iex.getMessage());
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
if (!_gotLocation) {
getLocationFromGoogle();
}
}
public void run() {
int bbMapsHandle = CodeModuleManager.getModuleHandle("net_rim_bb_lbs"); // OS 4.5 - 6.0
int bbMapsHandle60 = CodeModuleManager.getModuleHandle("net_rim_bb_maps"); // OS 6.0
if (bbMapsHandle > 0 || bbMapsHandle60 > 0) {
tryGetLocationFromDevice();
} else {
getLocationFromGoogle();
}
}
}
private void writeDataGoogleMaps(OutputStream out, int cellID, int lac) throws IOException {
DataOutputStream dataOutputStream = new DataOutputStream(out);
dataOutputStream.writeShort(21);
dataOutputStream.writeLong(0);
dataOutputStream.writeUTF("en");
dataOutputStream.writeUTF("Android");
dataOutputStream.writeUTF("1.0");
dataOutputStream.writeUTF("Web");
dataOutputStream.writeByte(27);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(3);
dataOutputStream.writeUTF("");
dataOutputStream.writeInt(cellID);
dataOutputStream.writeInt(lac);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.flush();
}
}
Your GPSThread object is currently declared as a private inner class within GPSHandler. If you want to stop execution (or indeed do anything with it) from outside the scope of GPSHandler you will need to mark it as public. You will also need to provide some public mechanism (e.g. a stop() method) to cancel the thread execution.
The most common way of doing this is to have a boolean flag inside your thread (e.g shouldStop) which is checked within your main execution loop inside run() to see if it should stop. When the stop() method is called shouldStop is set to true and your Thread will stop.
Here's a good example: How to stop threads in Java?
There's two groups of changes you should make.
Change the Stop Requested Flag
First, remember that encapsulation is a good thing in Object-Oriented languages. The isStopRequested() method, or stopRequested variable of the GPSHandler should not be used outside of that class. Your UI's GPSListener should not attempt to use either of those. I would change your GPSHandler to use this:
private static boolean stopRequested = false;
public synchronized static void requestStop() {
stopRequested = true;
}
private synchronized static boolean isStopRequested() {
return stopRequested;
}
Only requestStop() should be public. It looks like you made stopRequested public to allow the GPSListener to reset it. If it needs resetting, let the class that owns that variable do the resetting. For example, in GPSHandler:
/** call this to trigger a new location fix */
public void requestLocationUpdates() {
if (_gpsThread == null || !_gpsThread.isAlive()) {
// reset this stop flag:
stopRequested = false;
_gpsThread = new GPSThread();
_gpsThread.start();
}
}
requestLocationUpdates() is really the method that starts the thread, so it should be where stopRequested gets reset to false.
Also, another reason that you should not make stopRequested public and allow other classes to use it is that this is not generally thread-safe. One of the reasons to wrap stopRequested with the requestStop() and isStopRequested() methods is to add thread-safety. There's many ways to do that, but those two methods achieve thread-safety by being marked with the synchronized keyword.
Change How/Where You Check the Flag
After you make these fixes, you need to change where you check if a stop has been requested. You don't really want to check isStopRequested() in the refreshCoordinates() method. That method involves almost no work. Even though it starts the process of getting a location fix, that only starts a thread, but the actual work of getting the location is done on a background thread (your GPSThread). If requestStop() is called, it's very unlikely that it will be called in the middle of refreshCoordinates(), so that's not where you should check it.
Check isStopRequested() multiple times within the GPSHandler class's methods tryGetLocationFromDevice() and getLocationFromGoogle(). Those are the methods that perform slow processing. Those are the ones you might want to interrupt in the middle. So, something like this:
private void getLocationFromGoogle() {
try {
int cellID = GPRSInfo.getCellInfo().getCellId();
int lac = GPRSInfo.getCellInfo().getLAC();
String urlString2 = "http://www.google.com/glm/mmap";
if (isStopRequested()) return;
// Open a connection to Google Maps API
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(urlString2);
HttpConnection httpConn2;
httpConn2 = (HttpConnection)connDesc.getConnection();
httpConn2.setRequestMethod("POST");
// Write some custom data to Google Maps API
OutputStream outputStream2 = httpConn2.openOutputStream();//getOutputStream();
writeDataGoogleMaps(outputStream2, cellID, lac);
if (isStopRequested()) return;
// Get the response
InputStream inputStream2 = httpConn2.openInputStream();//getInputStream();
DataInputStream dataInputStream2 = new DataInputStream(inputStream2);
// Interpret the response obtained
dataInputStream2.readShort();
dataInputStream2.readByte();
if (isStopRequested()) return;
final int code = dataInputStream2.readInt();
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(code + "");
}
});
And in tryGetLocationFromDevice(), you could do this (make sure to add the member variable and new method below):
private LocationProvider _locationProvider; // must be a member variable!
public void requestStop() {
if (_locationProvider != null) {
// this will interrupt the _locationProvider.getLocation(300) call
_locationProvider.reset();
}
}
private void tryGetLocationFromDevice() {
_gotLocation = false;
try {
Criteria myCriteria = new Criteria();
myCriteria.setCostAllowed(false);
_locationProvider = LocationProvider.getInstance(myCriteria);
try {
Location myLocation = _locationProvider.getLocation(300);
setLocation(myLocation.getQualifiedCoordinates());
} catch ( InterruptedException iex ) {
// this may be caught if stop requested!!!!
System.out.println(iex.getMessage());
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
if (!_gotLocation && !isStopRequested()) {
getLocationFromGoogle();
}
}
Then, call the GPSThread.requestStop() method from the outer GPSHandler.requestStop() method:
public synchronized static void requestStop() {
stopRequested = true;
if (_gpsThread != null) {
_gpsThread.requestStop();
}
}

How to inherit partial class for stored procedure call

I have this class as parent class:
public partial class GetStuffResult
{
private int _Id;
private string _Name;
public GetStuffResult()
{
}
[Column(Storage="_Id", DbType="INT NOT NULL")]
public int Id
{
get
{
return this._Id;
}
set
{
if ((this._Id != value))
{
this._Id = value;
}
}
}
[Column(Storage="_Name", DbType="NVarChar(100)")]
public string Name
{
get
{
return this._Name;
}
set
{
if ((this._Name != value))
{
this._Name = value;
}
}
}
}
This is base class which has same methods with exception of an extra method:
public partial class GetStuffResult1
{
private int _Score;
private int _Id;
private string _Name;
public GetStuffResult1()
{
}
[Column(Storage="_Score", DbType="INT NOT NULL")]
public int Id
{
get
{
return this._Score;
}
set
{
if ((this._Score != value))
{
this._Score = value;
}
}
}
[Column(Storage="_Id", DbType="INT NOT NULL")]
public int Id
{
get
{
return this._Id;
}
set
{
if ((this._Id != value))
{
this._Id = value;
}
}
}
[Column(Storage="_Name", DbType="NVarChar(100)")]
public string Name
{
get
{
return this._Name;
}
set
{
if ((this._Name != value))
{
this._Name = value;
}
}
}
}
I have done inheritance before but i am totally confused how it will work in this scenario? How can i inherit GetStuffResult so that i can use its 2 methods and dont have to copy paste same code twice in GetStuffResult1.
Will appreciate if someone can give example with code as i am new to .net 3.5 and still trying to learn it.
I am not sure if I correctly understood your question. (Your current code for GetStuffResult1 shouldn't compile as you have define Id property twice.) If you are looking to inherit from GetStuffResult then this would do (See Inheritance):
public partial class GetStuffResult1 : GetStuffResult
{
private int _Score;
public GetStuffResult1()
{
}
[Column(Storage = "_Score", DbType = "INT NOT NULL")]
public int Id
{
get
{
return this._Score;
}
set
{
if ((this._Score != value))
{
this._Score = value;
}
}
}
}
Notice that I have removed _Id and _Name from the child class. This however will give you warning that:
GetStuffResult1.Id' hides inherited member
'ThreadConsoleApp.GetStuffResult.Id'. Use the new keyword if hiding
was intended.
The second thing I am thinking about your question if you are confused about using partial classes and you may need a single class in multiple source file. In that case you may use partial keyword. If that is the case and you don't need inheritance then you need to use a single name for the class. e.g. GetStuffResult. In that particular case your GetStuffResult1 will become:
public partial class GetStuffResult
{
private int _Score;
public GetStuffResult1()
{
}
[Column(Storage = "_Score", DbType = "INT NOT NULL")]
public int Id
{
get
{
return this._Score;
}
set
{
if ((this._Score != value))
{
this._Score = value;
}
}
}
}
This will be similar to having a single class with all the combined properties.
Edit:
To access the base class properties in the child class, you may use base keyword.
base.Id = 0;
base.Name = "SomeName";
To access the base class properties from the object of GetStuffResult1, see the following example.
GetStuffResult1 gsr1 = new GetStuffResult1();
gsr1.Id = 0;
gsr1.Name = "SomeName";
Here gsr1.Name is from the base class, you may use different name for Id in either base or child class so that it can be more clearer.

Resources