Return multiple values from a method - c#

Hi guys i'm having a problem regarding returning multiple values from a method. I'm using 'out' to return other value from a method, here the snippet:
public DataTable ValidateUser(string username, string password, out int result)
{
try
{
//Calls the Data Layer (Base Class)
if (objDL != null)
{
int intRet = 0;
sqlDT = objDL.ValidateUser(username, password, out intRet);
}
}
catch (Exception ex)
{
ErrorHandler.Handle(ex);
OnRaiseErrorOccuredEvent(this, new ErrorEventArgs(ex));
}
return sqlDT;
}
then when i compile having a error like this:
"The out parameter 'return' must be assigned to before control leaves the current method"
Anyone guys can help me solve this.

That means in all possibilities (inside and outside the if, in the catch), your result variable must be assigned.
The best approach would be to give it a default value at the start of the function:
public DataTable ValidateUser(string username, string password, out int result)
{
result = 0;
try
{
//Calls the Data Layer (Base Class)
if (objDL != null)
{
int intRet = 0;
sqlDT = objDL.ValidateUser(username, password, out intRet);
result = intRet;
}
//....

The parameter result of your method is marked as out. Parameters marked with out must be assigned within your method, i.e
result = 5;
This is enforced so callers of your method have the guarantee that the parameter that is passed with out is always set once your method finishes.

You're not setting the result variable in the method.
I'm guessing you want to add an extra line such as
result = intRet;

Related

Session exception error

My code is giving me this error i am not getting why and to do
"Error 13 An object reference is required for the non-static field, method, or property 'System.Web.UI.Page.Session.get'"
I am already using sessions to get a parameter at another page and method and works fine, now i want to use the same paramenter in a Schedualed Job i created for my app but is no working.
public static bool UpdateActivationResult(string recordId, string resultPart, string failureMessage, int reconciliation_count)
{
OracleConnection conn = new OracleConnection();
OracleTransaction transaction = null;
OracleCommand cmd;
string updateQuery = "";
int rowsUpdated = 0;
string notes = "";
string branch = clsUtility.GetHO;
clsUtility.CDFOperations operation = clsUtility.CDFOperations.CanNotActivateCard;
string userLoggedBranch = "";
try
{
userLoggedBranch = Session["userDegaS"].ToString(); //this row is giving me error
clsUtility.WriteLog4Net(recordId + " - " + resultPart + " - " + failureMessage, null, clsUtility.LogType.Debug, "");
using (conn = new OracleConnection(clsUtility.ConnectionString))
{ etc
i want to use this parameter in calling this method
if (reconciliation_count == 5 && !resultPart.Equals("SUCCESS"))
{
Utility.clsUtility.SendNotificationAsHTML(recordId, branch, operation, userLoggedBranch);
}
Any idea where am i doing wrong?
The Session property is a non-static property that is defined on the base Controller in .NET (msnd).
The the code listed with your question, you are trying to access this non-static method from without a static method. That is not possible.
You can solve it three ways:
If the method is within your controller, you can simply make it non-static in order to access the Session property.
You can also pass along the property you need (userLoggedBranch) as a parameter into your method UpdateActivationResult. Whatever action is calling that method will simply have to pass this value.
So something along the lines of:
public static bool UpdateActivationResult(
string recordId,
string resultPart,
string failureMessage,
int reconciliation_count,
string userLoggedBranch) {
// Your method code
Pass along the session itself, or something from which you can access the session (such as HttpContext, or the HttpRequest).
Declare userLoggedBranch as static variable or better is to simply access session in the respective method instead of passing it as a parameter

How to prevent static method from creating a null object

I have a static method that I call that checks if an object should be added and if calls the constructor if it should add it. Then if not it should really do nothing. I thought returning null would achieve this but it is creating an object with none of the properties being populated. This is then causing a runtime eror later.
This is my code:
public static WorkSheets AddSheet(string dataPath, string exportFile, string finalFile, string tabName)
{
if (File.Exists(dataPath + exportFile))
{
if (!tabName.Contains("Forecast") & !tabName.Contains("Sales"))
if (Functions.FileIsGood(dataPath + exportFile)) File.Copy(dataPath + exportFile, dataPath + finalFile, true);
return new WorkSheets(dataPath, exportFile, finalFile, tabName);
}
return null;
}
and my constructor:
public WorkSheets(string dataPath, string exportFile, string finalFile, string tabName)
{
this.ExportFile = dataPath + exportFile;
this.Path = dataPath + finalFile;
this.TabName = tabName;
this.DateError = !Functions.IsTodaysDate(ExportFile);
this.WorksheetDate = File.GetLastWriteTime(ExportFile);
this.SizeError = !Functions.IsCorrectSize(ExportFile);
this.WorksheetSize = new FileInfo(ExportFile).Length;
}
Then I call the method like this:
worksheets.Add(WorkSheets.AddSheet(CurrentWorkbook.DataPath, Constants.PipeExport, Constants.PipeFinalFile, "Pipe"));
The issue I am having is with the return null; what can I do so it doesn't add the null object.
You just need to get the return value from AddSheet in a temporary variable and check if it is null.
If it is null just don't add it to your list of worksheets
WorkSheets sheet = WorkSheets.AddSheet(CurrentWorkbook.DataPath,
Constants.PipeExport,
Constants.PipeFinalFile,
"Pipe"));
if(sheet != null)
worksheets.Add(sheet);
If you prefer to avoid repeating this check every time you add an element to the list then you can create a new class derived from List<T> and write your own Add method that performs the check for null and add to the underlying base class if the element to add is not null.
public class ListWorkSheets : List<WorkSheets>
{
public new void Add(WorkSheets source)
{
if(source != null)
base.Add(source);
}
}
Now you can declare
ListWorkSheets worksheets = new ListWorkSheets();
and use your current syntax without adding a null to your list
worksheets.Add(WorkSheets.AddSheet(CurrentWorkbook.DataPath,
Constants.PipeExport,
Constants.PipeFinalFile,
"Pipe"));
Try some conditional logic before adding the instance to the list.
IE
Worksheet tempWorkSheet = WorkSheets.AddSheet(CurrentWorkbook.DataPath, Constants.PipeExport, Constants.PipeFinalFile, "Pipe");
if (tempWorkSheet != null)
{
worksheets.Add(TempWorkSheet);
}
If your method has a declared return type you have to return that type or null.
You could throw an exception instead.
Or you change the return type to void and declare an out parameter for your result
Alternatively you could save the result of your call that instantiates the object and check for null.
var tmp = WorkSheets.AddSheet(foo);
if(tmp != null) {
worksheets.Add(tmp)
}
I'd recommend one of the following:
What #Steve said: split up your function call and check for null in the return.
Wrap your function call in a try/catch block then have your function return an exception if it can't find the file.
If it's a rare anomaly where a file can't be found then the exception is likely the 'correct' way to go from a methodology standpoint. If it's common for incorrect paths to be attempted, then returning null and having a check like Steve said is probably best. It's more a question of code methodology than technical requirement at that point.

How to pass var as another method`s parameter?

I am making a windows application.
At first I declared var and it contains another class method.
var ExtList = ExtTarget.GetExtTargets();
And GetExtTargets() is like this
public static List<ExtTarget> GetExtTargets()
{
var dt = SqlHelper.ExecuteDataTable(QueryHelper.ConnectionString,
#"
SELECT [seq],[SourceKind],[ExtKind],[DBKind],[ConnectionString]
,[FilePath],[TableName],[FileKind],[RowSplitter],[ColumnSplitter]
,[Title],[GroupName],[SyncOrder],[RepeatKind],[RepeatMonth]
,[RepeatDay],[RepeatHour],[RepeatMin],[RepeatWeek],[RepeatWeekNum]
,[LastSyncExecDate]
FROM [ExtTarget]
order by GroupName,SyncOrder");
return dt.Rows.Cast<DataRow>().Select<DataRow, ExtTarget>(a => ExtTarget.RowToModel(a)).ToList();
}
Then, I used it to foreach and then I want to pass Ext to another method's parameter.
Code is like this.
public void ProcessExtSync(object obj)
{
while (IsProcessGoing)
{
Thread.Sleep(ThreadDelay);
if (!IsProcessGoing) return;
var ExtList = ExtTarget.GetExtTargets();
foreach (var Ext in ExtList) // I want to use this Ext as parameter
{
while (IsSourceSyncGoing)
{
Thread.Sleep(ThreadDelay);
}
IsExtSyncGoing = true;
bool ExtSyncForceToRun = ConfigSettingHelper.Instance.IsServiceConfig(Words.ExtSyncForceToRun);
bool ExtSyncForceToRunOnlyError = ConfigSettingHelper.Instance.IsServiceConfig(Words.ExtSyncForceToRunOnlyError);
bool ExtSyncNeedToRun = ConfigSettingHelper.Instance.GetNextExecutingTime(Ext) < DateTime.Now;
if (ExtSyncForceToRun || ExtSyncNeedToRun)
{
//I want to pass Ext as parameter to this method
ServiceProcess.Instance.SyncExt();
if (ExtSyncForceToRun)
{
ConfigSettingHelper.Instance.SetServiceConfig(Words.ExtSyncForceToRun, false);
}
if (ExtSyncForceToRunOnlyError)
{
ConfigSettingHelper.Instance.SetServiceConfig(Words.ExtSyncForceToRunOnlyError, false);
}
}
if (!IsProcessGoing) return;
}
IsExtSyncGoing = false;
}
}
How can I modify that code? Please help me.
var is just a shortcut way of implicitly typing a variable. It saves some typing, but sometimes makes code harder to read when the reader can't determine the type. The compiler can figure out the strong type, though (or you'll get a compiler error), and if you hover over it in Visual Studio, the compiler will tell you the actual type.
With that out of the way, all you need to do is make sure that the method you want to pass your variable to takes in the type that you want to pass it (remember the type is not var, but in your case it is an ExtTarget).
The method you're calling should have a signature similar to this (although it may return any type):
public void SyncExt(ExtTarget extTarget)
{
// Implementation code here
}
Then in your code above you can call:
ServiceProcess.Instance.SyncExt(Ext);

MobileServiceSQLiteStore Defining a table with a generic Type

I was wondering if there's a way to use a generic Type when you define a table?
The DefineTable method takes your model to define the local table on the mobile phone. The model type is specified using angular brackets. However I am looking to pass a Type object and use this to define the table, however, you cannot use a variable inside angular brackets.
Below are code samples and more explanation of what exactly I am looking for...
This is how it is currently being implemented:
public async Task Init()
{
this.initialized = true;
const string Path = "syncorder.db";
var store = new MobileServiceSQLiteStore(Path);
store.DefineTable<Order>();
}
This is to get an idea of what I am trying to accomplish:
public async Task Init(Type tableType)
{
this.initialized = true;
const string Path = "syncorder.db";
var store = new MobileServiceSQLiteStore(Path);
//This is what i would like to do, but cant since its not possible to put variables inside angular brackets
store.DefineTable<tableType>();
}
I have also tried checking if it is possible to pass in the Type object as a parameter to the DefineTable method (since in some cases this is possible) but there is no overload allowing this.
//This is not possible...
store.DefineTable(tableType);
Anyhow all help is appreciated. Thanks!
So I figured out how to do this in case anyone runs into this issue below is the solution:
public Task Init(Type tableType)
{
try
{
this.initialized = true;
const string Path = "syncorder.db";
var store = new MobileServiceSQLiteStore(Path);
MethodInfo myDefineTable = RuntimeReflectionExtensions.GetRuntimeMethod(typeof(MobileServiceSQLiteStoreExtensions), "DefineTable", new Type[] { typeof(MobileServiceSQLiteStore) });
myDefineTable = myDefineTable.MakeGenericMethod(tableType);
myDefineTable.Invoke(null, new object[] { store });
for the parameters to pass into the method
}
catch (Exception ex)
{
this.initialized = false;
throw ex;
}
}
Hope this helps someone... cheers!
I think that you can just do the following:
public IMobileServiceSyncTable<T> Init<T>()
{
var store = new MobileServiceSQLiteStore(DatabaseName);
store.DefineTable<T>();
var Client = Client = new MobileServiceClient(SystemOptions.AzureStorage);
Client.SyncContext.InitializeAsync(store);
return Client.GetSyncTable<T>();
}

C# - 3 Tier Architecture. Error says No overload for method name takes 0 arguments

I am using 3 tier architecture in my C# Window Form. The thing I want to do is, hide the button if the data is exists. Here are my codes.
Class File
public bool checkIfExists(Variables variables) { // BelPar
SqlCommand check = new SqlCommand();
check.Connection = dbcon.getcon();
check.CommandType = CommandType.Text;
check.CommandText = "SELECT * FROM tbl";
SqlDataReader drCheck = check.ExecuteReader();
if(drCheck.HasRows == true)
{
drCheck.Read();
if (... && .. ||) // conditions where variables are being fetch
{
return false;
}
}
drCheck.Close();
return true;
}
Window Form
btn_save.Visible = !balpayrolldetails.checkIfExists(); // This is where I get the "No overload for method 'checkIfExists' takes 0 arguments.
Any help? Please leave or answer below. Thank you
To call a method, you need to call it by its exact name, which in this case is:
checkIfExists(Variables variables);
This tells us that to use this method, we need to pass it in an object of type Variables to be used in the method execution.
Whichever types are outlined in the method signature must be provided to successfully call a method.
You will need to update your call from
btn_save.Visible = !balpayrolldetails.checkIfExists();
to
btn_save.Visible = !balpayrolldetails.checkIfExists(someVariablesOfTheExpectedType);
Having the method signature:
public bool checkIfExists(Variables variables)
It should be called by passing an object of type Variables to the method:
btn_save.Visible = !balpayrolldetails.checkIfExists(anInstanceOfVariables);
But if it's acceptable for you to call the method parameter-less and your method is written in a way that can tolerate having variables with null value, you can change the signature to this:
public bool checkIfExists(Variables variables=null)
And then you can call it this way:
btn_save.Visible = !balpayrolldetails.checkIfExists();

Categories