Void method in class c# - c#

I have a problem with calling a method void for a string.
I've created a class:
public string SendData(string val1){ return val1; }
public void RecoverBirth()
{
clsConnectionClass conn = new clsConnectionClass();
SqlCommand cmd = new SqlCommand();
SqlDataReader dr;
cmd.CommandText = "select * from birthday";
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
SendData(dr[1].ToString() + " " + dr[2].ToString() + "\r\n");
}
}
}
}
And then I try to retrieve the data from the class
private void button_Click(object sender, EventArgs e)
{
var _test = new Test();
string Result = _test.RecoverBirth();
}
This error occurs:
Can't convert method "void" to "string"
I need RecoverBirth method to be Void not "string", because it has a lot of different cycle and not everything return something, and if I declare it as string I have to use a lot of return null.
Is there a (better) way to do this?

public class Test
{
public string StringValue { get; set;}
public void DoSome()
{
while(some code here)
{
//something here
//set StringValue to what you like
this.StringValue = "this is now the text";
}
}
}
and then
private void button_Click(object sender, EventArgs e)
{
var test = new Test();
test.DoSome();
var result = test.StringValue;
}

The void keyword in the C# language indicates that a method returns nothing.
You should use the return keyword which means that a method returns only one value. What type of return value of the method you should specify at signature of the method. For example:
public string MethodA(bool isItReally)
In the above code return value is type of string.
So, you should correct the method like that:
Your updated code:
class Test
{
public string RecoverBirth()
{
clsConnectionClass conn = new clsConnectionClass();
SqlCommand cmd = new SqlCommand();
SqlDataReader dr;
cmd.CommandText = "select * from birthday";
dr = cmd.ExecuteReader();
string colValue;
if (dr.HasRows)
{
while (dr.Read())
{
colValue= dr[1].ToString() + " " + dr[2].ToString() + "\r\n");
}
}
return colValue;
}
}
It is not possible to assign to a string variable a value of void method as
void method returns nothing.

You better start with basic ... It's very basic things in programming dude..
class Test
{
public string s1(string val) { return val; }
public string DoSome()
{
while(some code here)
{
s1(result1 + result2);
}
//Must return string to get as string
return someVariableOfString;
}
}

If you strictly want your method to be of void return type then pass parameter by reference with out keyword to the method, and in this case method can directly change the reference value and so you can get the new value back in 'calling' code.
You can learn more on out in MSDN
public void DoSome(out string result)
{
//Do whatever stuff you want and assign the new value(string in your case) to the parameter
result = "My new string after some processing.";
}
Calling:
string result;
DoSomething(out result); //After successful execution of this line `result` will have newly assigned string value from within the function
Hope this help you..

Ignoring all the nagging doubts about a design where something like this makes sense... you could use an argument to emit whatever output necessary. For example:
public void DoSomething(Action<string> someAction = null)
{
// When it's time to emit a result, just do
if (someAction != null) someAction("Hello world!");
}
Which you can then call as
var sb = new StringBuilder();
DoSomething(s => sb.AppendLine(s));
If you're calling from a place that doesn't care about the "return value", you can just omit the argument:
DoSomething();
But seriously, your design needs lots of work if you have to do something like this. Also, there's nothing wrong with return null - it's hard to see why that would be an issue in your code. Just replace all those return; with return null; or something. But it seems like your method simply does way too many things if you care about the distinction.

If you need your method to return void, you could use the out keyword to pass in your result as a reference variable, like this:
class Test
{
public string SendData(string val1){ return val1; }
public void RecoverBirth(out string result)
{
clsConnectionClass conn = new clsConnectionClass();
SqlCommand cmd = new SqlCommand();
SqlDataReader dr;
cmd.CommandText = "select * from birthday";
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
result += SendData(dr[1].ToString() + " " + dr[2].ToString() + "\r\n");
}
}
}
}
And your call:
private void button_Click(object sender, EventArgs e)
{
var _test = new Test();
string result = null;
_test.RecoverBirth(out result);
}

Related

how to pass generic list parameter into a method?

I am getting phone contacts into a list<> and saving it in a database.
Below is my code.
This is my method to get the contacts-List
protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
try {
SetContentView(Resource.Layout.Main);
TextView txtcount = this.FindViewById<TextView>(Resource.Id.textView1);
List<PersonContact> a1 = GetPhoneContacts();
Phone gp = new Phone();
gp.insertContact(a1);
} catch (System.Exception ex) {
alert(ex.Message);
}
}
Via the following method I am trying to store contacts in database
[WebMethod]
public string insertContact<T>(List<PersonContact> a) {
OpenConnection();
if (a.Count > 0) {
for (int i = 0; i < a.Count; i++) {
string str = "insert into phone_contact (FirstName,LastName,PhoneNumber)values('" + a[i].FirstName + "','" + a[i].LastName + "','" + a[i].PhoneNumber + "')";
SqlCommand cmd = new SqlCommand(str, con);
cmd.ExecuteNonQuery();
}
return "1";
} else {
return "1";
}
}
public class PersonContact {
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
}
I am getting an error while passing parameter
gp.insertContact(a1);
Your method is generic, as it introduces a new type parameter T. That's what the <T> at the end of the method name means.
However, you don't use T anywhere - so just make it a non-generic method:
public string InsertContact(List<PersonContact> a)
At the same time, I would very strongly urge you to change the way you're doing database access: it's currently vulnerable to SQL injection attacks. Instead, you should use parameterized SQL: have one parameter for each of FirstName, LastName and PhoneNumber.
You're also returning "1" regardless of the input. Your method could be written more simply as:
// Consider renaming to InsertContacts, as it's not just dealing with a single
// contact
public string InsertContact(List<PersonContact> contacts)
{
// You should almost certainly use a using statement here, to
// dispose of the connection afterwards
OpenConnection();
foreach (var contact in contacts)
{
// Insert the contact. Use a using statement for the SqlCommand too.
}
return "1";
}
That's assuming you need the value returned at all - if you're always returning the same value, why not just make it a void method?

How can I get data read from a database to show in a ListBox using C#?

I have a databsase called Patients with Table Conditions that has the following fields:
ConditionID(PK) int(50) AI,
ID_No(PK)(FK) bigint,
Date date,
Diagnosis varchar(50),
Notes varchar(max)
I have a C# windows form application called Records which should read the data in the Table Conditions and show it under the tab Condition in tabcontrol1 in the Records Form.
I have another class called Misc.cs that has the connection string (as my project has many forms and I avoided having the code for connecting duplicated on every form)
Below is code from Misc.cs that connects and reads data from the database:
class Misc
{
SqlConnection con = new SqlConnection(#"DataSource=.\SQLEXPRESS;AttachDbFilename=G:\BiometricSystem\BiometricSystem\Patients.mdf;Integrated Security=True;User Instance=True");
SqlCommand cmd = new SqlCommand();
SqlDataAdapter a = new SqlDataAdapter();
SqlDataReader dr;
public static long Id;
public void connect()
{
cmd.Connection = con;
}
public void getConditions()
{
connect();
con.Open();
cmd.CommandText = "SELECT * FROM Condition WHERE ID_No = '" + Id + "'";
dr = cmd.ExecuteReader();
Records r = new Records();
if (dr.HasRows)
{
while (dr.Read())
{
r.setdiagnosis(dr[0].ToString());
r.setDate(dr[1].ToString());
r.setNotes(dr[2].ToString());
r.printConditions();
}
}
else
System.Windows.Forms.MessageBox.Show("No records to display");
closeConn();
}
}
This code is invoked in Records.cs as follows:
public partial class Records : Form
{
Misc misc = new Misc();
long patID = Misc.Id;
private string diagnosis, datum ,dinota;
public Records()
{
InitializeComponent();
diagnosis = "";
datum = "";
dinota = "";
}
public void setdiagnosis(string dx)
{
diagnosis = dx;
}
public string getdiagnosis()
{
return diagnosis;
}
public void setDate(string date)
{
datum = date;
}
public string getDate()
{
return datum;
}
public void setNotes(string notes)
{
dinota = notes;
}
public string getNotes()
{
return dinota;
}
private void tabControl1_Selected(object sender, TabControlEventArgs e)
{
switch (tabControl1.SelectedIndex)
{
case 0:
{
//Nothing to do here
}
break;
case 1://tab containing where I want to display the data
misc.getConditions();
//MessageBox.Show("Conditions have been selected");
break;
}
}
public void printConditions()
{
MessageBox.Show(getdiagnosis()+"\t"+getDate()+"\t"+getNotes());
listConditions.Items.Add(getdiagnosis() + "\t" + getDate() + "\t" + getNotes());
}
}
The messagebox shows the requested data, but listbox listConditions does not, I do not know what is the problem.
PS: the messagebox was just to prove to myself that the requested data was indeed returned.
PPS: could you also suugest an alternative of specifying the connection string that doesn't require the absolute path to the solution.

Test to compare array method fails

I am testing my class. My method returns an array of insurance percentage paid and financial limit for the given policy id.
For policy id 43 its financial limit is null and its percentage insurance paid is 95.75.I am trying to test this but my test keep failing. Could any one tell where am doing wrong?
here is my class
public class PatientInsuranceLimits : System.Web.UI.Page
{
String sqlConStr = ConfigurationManager.ConnectionStrings["connectionname"].ToString();
public String[] generalLimits(String policyID)
{
String []resultset = new String[2];
SqlConnection con = new SqlConnection(sqlConStr);
String sqlQuery1 = "Select InsurancePaidPercentage as iPP, FinancialLimit as fLimit from Policy where ID=#poid";
SqlCommand cmd1 = new SqlCommand(sqlQuery1, con);
cmd1.Parameters.AddWithValue("#poid", policyID);
try
{
con.Open();
SqlDataReader r = cmd1.ExecuteReader();
while(r.Read()){
resultset[0] = r[0].ToString();
resultset[1] = r[1].ToString();
}
r.Close();
}
catch(Exception ex){
}
finally{
con.Close();
}
return resultset;
}
here is my test class
namespace _10_06_13_test
{
[TestClass()]
public class PatientInsuranceLimitsTest
{
private TestContext testContextInstance;
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
[DataSource("System.Data.SqlClient", "Data Source=servername_lab;Initial Catalog=IDKit;User ID=userid;Password=password", "mytable", DataAccessMethod.Sequential), TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("C:\\Users", "/")]
[UrlToTest("http://localhost:51063/")]
public void generalLimitsTest()
{
SurvivalHealth.PatientInsuranceLimits target = new SurvivalHealth.PatientInsuranceLimits();
string policyID = "43";
string[] expected = new string[] {"95.75"};
string[] actual;
actual = target.generalLimits(policyID);
Assert.AreEqual(expected, actual);
}
}
}
The function returns an array containing null and "19.75".
You need to change the value assigned to expected to { null, "19.75"}.
However if you are using .net 2 or later I would recommend that you change the method to return a tuple to prevent this sort of errors. It is probably also a good idea to store numbers in a numerical data type like decimal.

Stackoverflow Exception on get function for a property

I have the following simple class to manage my SQL database operations
public class DatabaseManager
{
private string CommandString
{
set { CommandString = GetCommandString(commandtype); }
get { return CommandString; }
}
public string commandtype
{
set;
get;
}
public DatabaseManager(string commandtype)
{
commandtype = this.commandtype;
CommandString = GetCommandString(commandtype);
}
public DatabaseManager()
{
}
public static SqlConnection CreateConnection()
{
return new SqlConnection(Properties.Settings.Default.connectionString);
}
//returns a datatable if the command requires a dataadapter
public DataTable ExecuteSelect()
{
var x = new DataTable();
using (var da = new SqlDataAdapter(CommandString, DatabaseManager.CreateConnection()))
{
da.Fill(x);
}
return x;
}
private string GetCommandString(string commandtype)
{
switch (commandtype)
{
// select commands
case ("SELECTMARGINS"): CommandString = "select * from margins"; break;
case ("SELECTRANKS"): CommandString = "select * from ranks"; break;
/...and other commands
return CommandString;
}
}
i am getting a Stackoverflow exception on get { return CommandString; }
The get function is your problem
get { return CommandString; }
This is the morale equivalent of the following
public string GetCommandString() {
return GetCommandString();
}
This will just create infinite recursion and eventually a StackOverflowException will be thrown. You need to change the get and set to operate on a backing field which holds the actual value and use that instead
private string _commandString;
public string CommandString {
get { return _commandString; }
set { _commandString = GetCommandString(commandtype); }
}
You can't have a property return itself (it creates an infinite loop).
private string _CommandString;
public string CommandString
{
set { _CommandString = GetCommandString(commandtype); }
get { return _CommandString; }
}
You can't have a Get function return itself, it will just cause it to infinitely attempt to retrieve itself until the stack overflows.
Create a private variable to get and set to:
private string _CommandString;
private string CommandString
{
//Also you probably want to change commandtype to value, since you will be
//discarding whatever you attempt to set the variable as
set { _CommandString = GetCommandString(commandtype); }
get { return _CommandString; }
}
You cannot set or even get CommandString, you have to create a private variable in this case.
private string _commandString;
public string CommandString
{
set { _commandString = GetCommandString(commandtype); }
get { return _commandString; }
}
What is happening in your current code is that you are doing something like this:
CommandString = "x";
which calls
CommandString = GetCommandString(type);
which calls
CommandString = GetCommandString(type);
etc....so it keeps looping until it overflow. The private variable keeps you from setting the same property over and over again
Also, it looks like you are never actually using the value passed into the set function, which seems like a bug

c# property won't work?

hello guys i have a form... and i set my properties if the user will click the submit button and after then i will call my add_data function which contains my database query...but the problem is the properties I've set in my form will become empty in my add_data function...why this is happening?
actually i already try adding a messagebox in my form which contains the data in my properties after setting my properties value and it works fine but when i add it to my databasecon class the messagebox shows null... i try also putting my properties and database query function in the same class and it's working but what i want is to separate my properties and my database query functions...
this is the codes in my properties
class persons
{
//person attributes
private string fname;
private string lname;
private string age;
private string gnder;
private string address;
//initialize
public persons()
{
this.fname = "";
this.lname = "";
this.age = "";
this.gnder = "";
this.address = "";
}
//set and get properties
public string p_fname
{
get { return this.fname; }
set { this.fname = value; }
}
public string p_lname
{
get { return this.lname; }
set { this.lname = value; }
}
public string p_age
{
get { return this.age; }
set { this.age = value; }
}
public string p_gender
{
get { return this.gnder; }
set { this.gnder = value; }
}
public string p_address
{
get { return this.address; }
set { this.address = value; }
}
}
this is the codes in my form
public partial class add : Form
{
persons p = new persons();
databasecon d = new databasecon();
private void addbtn_Click(object sender, EventArgs e)
{
p.p_fname = this.fname.Text;
p.p_lname = this.lname.Text;
p.p_age = this.age.Text;
p.p_gender = this.gender.Text;
p.p_address = this.address.Text;
d.add_data();
this.Close();
}
}
and this is the codes in my database connection and queries
class databasecon
{
OleDbConnection con = new OleDbConnection();
persons p = new persons();
public databasecon()
{
con.ConnectionString = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=../dbsample.mdb";
}
public void add_data()
{
try
{
con.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO person(u_fname,u_lname,u_age,u_gender,u_address)VALUES('" + p.p_fname + "','" + p.p_lname + "','" + p.p_age + "','" + p.p_gender + "','" + p.p_address + "')";
cmd.Parameters.AddWithValue("u_fname", p.p_fname);
cmd.Parameters.AddWithValue("u_lname", p.p_lname);
cmd.Parameters.AddWithValue("u_age", p.p_age);
cmd.Parameters.AddWithValue("u_gender", p.p_gender);
cmd.Parameters.AddWithValue("u_address", p.p_address);
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
MessageBox.Show("Error : " + e);
}
finally
{
con.Close();
MessageBox.Show("New person has been successfully added.");
}
}
}
You need to pass p as a parameter to the add_data method.
public void add_data(persons person)
then call it with the parameter:
d.add_data(p);
and use the properties of person in the method:
cmd.Parameters.AddWithValue("u_fname", person.p_fname);
cmd.Parameters.AddWithValue("u_lname", person.p_lname);
cmd.Parameters.AddWithValue("u_age", person.p_age);
cmd.Parameters.AddWithValue("u_gender", person.p_gender);
cmd.Parameters.AddWithValue("u_address", person.p_address);
you create databasecon() in form and then call add_data method and you don't pass 'persons' instance. in databasecon you use persons istnace which is field in this class. you soudl add parameter do add_data method and pass instance or 'persons' you want to save and use it in command
Your p fields in your add and databasecon classes are separate. When you call d.add_data(), the d object can only see its instance of persons p ....
To fix this, pass the persons object into the add_data method.
class databasecon{
// Remove this line, we pass it into the function below
/* persons p = new persons(); */
public void add_data(persons p){
try{
// same code as before
}catch(Exception e){
// same code
}
finally{
// same
}
}
}
You have an instance of Person class which you fill and then use an instance of databasecon which is completely not conntected to the person class you filled.
Change add_data() to
public void add_data(person p) { ... }
this will use the properties from p passed as parameter.
You call it like this
d.add_data(p);
Except for that have a look at some C# for begginers book.
Overlooking the fact that your code is extremely poorly written.
You are not passing in the persons class that you created.
Something like
public void add_data(persons p) {//..blah}
Then
private void addbtn_Click(object sender, EventArgs e) {
p.p_fname = this.fname.Text;
p.p_lname = this.lname.Text;
p.p_age = this.age.Text;
p.p_gender = this.gender.Text;
p.p_address = this.address.Text;
d.add_data(p);
this.Close();
}
From what I can see in the code above, you call add_data from your databasecon class, which has an instance p of Person. Since you are not passing a Person object to your add_data method, the empty, unset p object is what is being saved to the database.
Adding a Person parameter to add_data and use that when saving the data to the database.
There are several things I don't like in your code.
Let's start however with your specific problem:
Your code contains also a source of security issues and malignous SQL code injection.
You are saving always an empty person and there is a problem with your SQL connection string.
Try this code instead.
private void addbtn_Click(object sender, EventArgs e)
{
try
{
persons p = new persons(); // we use a new instance of person class
p.p_fname = this.fname.Text;
p.p_lname = this.lname.Text;
p.p_age = this.age.Text;
p.p_gender = this.gender.Text;
p.p_address = this.address.Text;
d.add_data(p); // we save the instance of persons
this.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error : " + e);
}
}
...
class databasecon
{
public void add_data(person p) // we need a person as parameter
{
OleDbConnection con = new OleDbConnection();
con.ConnectionString = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=../dbsample.mdb";
con.Open();
try
{
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
// this is the correct sql command string
cmd.CommandText = "INSERT INTO person(u_fname,u_lname,u_age,u_gender,u_address) " +
VALUES (#u_fname, #u_lname, #u_age, #u_gender, #u_address)";
cmd.Parameters.AddWithValue("u_fname", p.p_fname);
cmd.Parameters.AddWithValue("u_lname", p.p_lname);
cmd.Parameters.AddWithValue("u_age", p.p_age);
cmd.Parameters.AddWithValue("u_gender", p.p_gender);
cmd.Parameters.AddWithValue("u_address", p.p_address);
cmd.ExecuteNonQuery();
}
finally
{
con.Close();
}
}
...
}
Now let's talk about code style.
Is a good thing to use CamelCase style in your code, look on the web about C# CamelCase:
Classes and properties should all start with a capitalized letter.
Your class express a single person not a list of persons so its name should be public class Person.
Avoid the use achronims or of short names when you can...
p_lname should be LastName, people will thanks you if you make your code more readable, C# is not C and C# is not PHP!
A field or a property with a longer name will not consume more memory than a property with a short and unreadable name :)
Use always strong typing... age is not a string, age is an integer.
The property should be public int Age, not a string!
Never use MessageBox in your non-visual classes.
Try to catch for exceptions in your client code, not in your library code!
I dont know if I 100% understand the issue about I guess it's because your inserting an empty persons class into the db.
Your `add_data method should take a person object like so.
public void add_data(persons obj)
{
p = obj;
you must pass person object to add_data method
public void add_data(persons p)
{
...
}
and call it:
d.add_data(p);

Categories