In my selectUser class I have:
public checkEmail(string email)
{
peopleTableAdapters.PeoplesTableAdapter p = new peopleTableAdapters.PeoplesTableAdapter();
return p.checkEmail(email);
}
In the client side code I have:
protected void Button1_Click(object sender, EventArgs e)
{
selectUser s = new selectUser();
try
{
s.checkEmail(email.Text);
}
catch(Exception e)
{
}
}
I am getting this error with the "return p.checkEmail(email);" the error is:
"Error 307 Since 'authentication.checkEmail(string)' returns void, a return keyword must not be followed by an object expression"
Does anyone understand what I am doing wrong?
I dont want to return any data because its not needed I just want to return something so it succeeds in the try statement.
This has no return type:
public checkEmail(string email)
I'm surprised this even compiles, but maybe the compiler assumes void when nothing is specified? I didn't know it did that. But either way, there's no return type. So this won't work:
return p.checkEmail(email);
If the method doesn't have a return type, then it can't return anything. You also don't do anything with the returned value:
s.checkEmail(email.Text);
So you don't need to return anything at all.
Furthermore, the error also suggests that p.checkEmail(email) itself doesn't return anything. So trying to return something which itself is a void return type is just compounding the problem.
Since nothing in this code returns any value, you can probably resolve this by simply not trying to return anything at all:
public void checkEmail(string email)
{
peopleTableAdapters.PeoplesTableAdapter p = new peopleTableAdapters.PeoplesTableAdapter();
p.checkEmail(email);
}
To exp[and on David's answer, if you don't want either checkEmail method to return a value, then you will need to throw an exception for an invalid e-mail at whatever point in the chain you are determining that it is or isn't valid.
This can be done using throw new ArgumentException() replacing ArgumentException with whatever exception type you feel is appropriate.
Related
I'm running into an odd scenario that doesn't happen on my PC, but does for a coworkers.
I have this piece of code:
LoaderHelpers.SetStringValue<blah>(this, "x", $"x response in Header",
() => jsonData.x.response[0].value, false);
The problem is that sometimes, "jsonData.x" is null and, for my coworker a 'cannot bind to null at runtime exception' is thrown, but not for me there isn't. I have code to handle the null scenario, but it's like his code never gets to that point and fails at the call level.
jsonData is of type dynamic.
The method code that handles the null scenario:
public static void SetStringValue<T>(IValidate data, string propertyName,
string valuePath, Func<string> value, bool required)
{
if (data.GetType().GetProperty(propertyName) != null)
{
try
{
if (string.IsNullOrEmpty(value()))
{
if (required)
data.DataValidationErrors.Add($"{valuePath} can't be empty");
data.GetType().GetProperty(propertyName).SetValue(data, null);
}
else
{
data.GetType().GetProperty(propertyName).SetValue(data, value());
}
}
catch
{
//property doesn't exist
if (required)
data.DataValidationErrors.Add($"{valuePath} doesn't exist");
data.GetType().GetProperty(propertyName).SetValue(data, null);
}
}
else
{
throw new NullReferenceException($"In {data.GetType()} => SetStringValue. " +
$"Passed property {propertyName}, but property doesn't exist.");
}
}
Again. Works perfect for me, but not for him. I'm completely lost. Maybe I don't understand how the lamba/function parameters work 100%, but I thought it only got evaluated when value() is invoked.
I should also mention that when I debug this code, I can step into the Nuget package and when he hits the same line, he can't. This maybe a useful hint.
If jsonData (or jsonData.x) is null (as it seems to be at this point) it will crash and give you that error every time you call the method value().
You need to check why jsonData.x is null. Maybe it´s a race condition caused by another thread setting this value to null, maybe it´s because a bad jsonData initialization... Can´t say since that code is not here.
There are so many things wrong with your code, i can't resist.
First of all, instead of copy/pasting the same stuff over and over, you might want to use a variable:
var property = data.GetType().GetProperty(propertyName);
Second, you pass a Func<string> and execute it multiple times, why is it even a function then? Yet again, better only evaluate it once and use a variable...
var unwrapped = value();
That would solve the issue, that Roberto Vázquez' answer adresses.
Then you are misusing NullReferenceException, instead rather use a ArgumentException
Next issue, that valuePath is only used in the exception message, that is a poor design to my beliefs.
The generic T parameter isnt even used, so get rid of it.
Last but not least, that catch-block doing the exact thing that could possibily throw the exception again, i cant see any reason why you would do this.
Finnaly this whole thing becomes a little more clear but its still a mess.
public static void SetStringValue(IValidate data, string propertyName,
string valuePath, Func<string> value, bool required)
{
if(data == null)
throw new ArgumentNullException(nameof(data));
var property = data.GetType().GetProperty(propertyName);
if(property == null)
throw new ArgumentException($"In {data.GetType()} => SetStringValue. " +
$"Passed property {propertyName}, but property doesn't exist.");
var unwrapped = value();
try
{
if (string.IsNullOrEmpty(unwrapped))
{
if (required)
data.DataValidationErrors.Add($"{valuePath} can't be empty");
unwrapped = null; // this might be unecessary.
}
property.SetValue(data, unwrapped);
}
catch(Exception e)
{
// This is probably a bad idea.
property.SetValue(data, null);
if (required)
data.DataValidationErrors.Add(Atleast put a better message here. e.Message ...);
}
}
I understand I cannot modify default(T).
How to change what default(T) returns in C#?
In my situation, we have several classes that implement functionality of the base class:
T RequestForData<T>(string request)
{
return default(T);
}
I need to modify this default functionality to handle a "Refresh" call, which I can write like this:
private DataContext _dc;
T RequestForData<T>(string request)
{
if (request == "Refresh")
{
if ((_dc != null) && !_dc.HasPendingChanges())
{
_dc.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues);
}
}
return default(T);
}
These can now be called from the MDI parent form:
foreach (var form in this.Forms)
{
form.RequestForData<bool>("Refresh");
}
As you can see from the way I have called it, RequestForData returns a Boolean value.
If I handle the call in one of my forms, I want to return TRUE, but this returns an error in Visual Studio.
Cannot implicitly convert type 'bool' to 'T'
FYI: I tried a cast, too, but the compiler says that is redundant.
How do I handle returning a value type as specified by ?
Perhaps you could use a Nullable<bool>:
var result = form.RequestForData<bool?>("Refresh") ?? true;
However, I don't see the point in your generic method returning a value at all. Why not just make it a void method? What's the information that this return value carries?
Assuming you are sure nobody will use your method with, let's say string generic argument, you could avoid the compiler error by doing the following:
return (T)(dynamic)true;
Of course it will lead to runtime error in case bool can't be cast to T. But for me such solution worked pretty well once while implementing typed data-reader from SQL-DataTable.
PS: But still I don't believe this hack is justified for this particular method. It's really primitive and can't return anything other then boolean, can't work with any other generic argument. So you better either make it return bool, or void as was suggested in other comments.
The question got a downvote.
I think people on here vote it down when they think they know everything and there is no way they can see to solve the problem.
Here is how we resolved the coding dilemma:
T RequestForData<T>(string request)
{
if (request == "Refresh")
{
if ((_dc != null) && !_dc.HasPendingChanges())
{
_dc.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues);
return (T)Convert.ChangeType(true, typeof(T));
}
}
return default(T);
}
If anyone sees why that will not work, feel free to comment.
try this implementation may work :
bool RequestForData<T>(string request)
{
return true;
}
or in a more flexible form :
object RequestForData<T>(string request)
{
if(conditionOk)
return default(T);
else
return false;
}
Why are exceptions always accepted as a return type (thrown)?
Valid example 1:
public string foo()
{
return "Hello World!";
}
Invalid example (obviously):
public string foo()
{
return 8080;
}
Valid example 2:
public string foo()
{
throw new NotImplementedException("Hello Stackoveflow!");
}
I can see that my "Invalid Example" is 'throwing' and not 'returning' the Exception, however, my method does never return the type defined by the method. How come my compiler allows this to compile?
Exceptions are not return types, exceptions indicate an error in the method and that it cannot continue.
Your valid example 2 does not return anything, the compiler knows that it will always throw an exception, so it does not need to worry about returning.
If you had:
public string foo(int something)
{
if(something > 10){
throw new NotImplementedException("Hello Stackoveflow!");
}
}
it would complain, because you are not returning a value all the time.
Also, from your example, if you had: string val = something() in your code, val would never get set, because an exception is not a return value.
However, it is valid code, your function can either return a value based on its signature or throw an exception. If anything, you might expect a warning by the compiler. I'm not sure about C#, but in java if you have code that is determined to be unreachable you will get warnings, such as:
public string foo(int something)
{
throw new NotImplementedException("Hello Stackoveflow!");
return "OK";
}
This code would give you a warning, because it is impossible for this method to reach the return statement (but it is still valid code, at least if it were Java).
You can read about exceptions here: MSDN
Exceptions give you information about ocurred error. You can easly handle and throw them.
How do I know the log the last property that is null?
For example,
var a = "somevalue";
......
......
if(a == null)
{
Log.Error(MethodBase.GetCurrentMethod().Name + "Property : a is null");
//blah blah
}
Like how I use the reflection to get the current method name, there should be some means by which I can log the latest local variables (or a property or fields)
that is being compared ? I use, log4net by the way to log the errors.
1) Is there any method to achieve this or should we manually log it?
2) Is there any custom method that prints the class -> MethodName -> Propertyname(or FieldName) that is null?
Thanks for your time in advance.
As mentioned by #fsimonazzi, "a" would be a local variable.
That being said there is still no way to examine the current compare operation as in MSIL there is no formal concept of an IF block - only conditional jumps.
If you wanted to get really crazy with the reflection, you may be able to find the current executing instruction and look around near that for a variable, but even then, you will not find the name - only a reference - as names are only used prior to compilation.
Either way, reflection is not going to help you here.
Instead, try using Exceptions - specifically ArgumentNullException. This body of code would become:
void doStuff(string param1, int param2)
{
if (param == null)
throw new ArgumentNullException("param1", "param1 must not be null");
if (param2 < 0)
throw new ArgumentOutOfRangeException("param2", "param2 should be non-negative.");
//method body
}
then, when you call the method, you can catch the exception and log it - no matter what it may be.
public static void Main(string[] args)
{
try
{
doStuff(null, 3);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
Tools like FxCop can help make sure that you are properly validating each parameter.
Properties are actually implemented as methods, so reflection could help you there. If, for example, you were validating in a property and wanted to log the position automatically, you could.
private object _cachedObject = null;
public object CachedObject
{
get
{
if (_cachedObject == null)
{
log(MethodBase.GetCurrentMethod().Name, "creating cached object");
_cachedObject = createCachedObject();
}
return _cachedObject;
}
}
The .Net Framework 4.5 also brings with it a new attribute that can be used to replace the MethodBase.GetCurrentMethod().Name construct you are using to get the method name. See [CallerMemberNameAttribute][3].
I have a code block that does not return the expected data values.
protected void Page_Load(object sender, EventArgs e)
{
corpEmployee.Employee editEmp = new corpEmployee.Employee();
editEmp.EmployeeID = PatientCustomerID.Value;
corpCustomerMgr.GetEmployeeRecord(editEmp);
tboxFirstName.Text = editEmp.EmpFirstName.ToString();
tboxLastName.Text = editEmp.EmpLastName.ToString();
tboxCity.Text = editEmp.EmpCity.ToString();
tboxAddress.Text = editEmp.EmpAddrLine1.ToString();
}
public static void GetEmployeeRecord(corpEmployee.Employee QueryData)
{
try
{
List<corpEmployee.Employee> empRecord = new List<corpEmployee.Employee>();
corpCustomerDAL.GetEmployeeData(empRecord, QueryData);
}
catch (Exception ex)
{
LogAppError(ex.ToString());
}
}
When corpCustomerDAL.GetEmployeeData(empRecord, QueryData); is executed, empRecord is returned with the Employee object with correct property values. However, when the code comes back to corpCustomerMgr.GetEmployeeRecord(editEmp); the employee object has null values.
How can I get the Employee object values back to the Page_Load routine?
You could either return the object back in the GetEmployeeRecord static method or you could include ref in front of your arguments so that you are passing the employee in as a reference instead of copying the variable.
I would recommend returning your data back vs using ref as your method name seems misleading, among other reasons.
Based on your comments, it looks like you are populating empRecord with the employee data you require. The simplest option is to return the populated record from GetEmployeeRecord:
public static corpEmployee.Employee GetEmployeeRecord(corpEmployee queryData)
{
List<corpEmployee.Employee> empRecord = new List<corpEmployee.Employee>();
corpCustomerDAL.GetEmployeeData(empRecord, QueryData);
return empRecord.Count == 0 ? null : empRecord[0]; //or empRecord.FirstOrDefault()
}
You should then change the start of your Page_Load handler to:
corpEmployee.Employee queryEmp = new corpEmployee.Employee();
queryEmp.EmployeeID = PatientCustomerID.Value;
corpeEmployee.Employee editEmp = corpCustomerMgr.GetEmployeeRecord(queryEmp);
Two immediate thoughts occur:
Your exception handling needs work. You shouldn't be catching Exception, and you shouldn't be silently swallowing exceptions at all. It could well be that an exception is being thrown, and that's why you're not getting the data.
You've got a Get*** method - that should be returning data. It appears you're expecting the results to be put into an object... that's a confusing way of getting data out of a method. It would be clearer if your method signature were something like:
public static Employee GetEmployeeRecord(string employeeId)
Most likely what's happening is that your employee object that you're passing in is being copied, and is destroyed when the function terminates.
To better illustrate, I've added some comments:
public static void GetEmployeeRecord(corpEmployee.Employee QueryData)
{
//QueryData is a newly created Employee here, and is NOT the same one that was passed in.
try
{
List<corpEmployee.Employee> empRecord = new List<corpEmployee.Employee>();
corpCustomerDAL.GetEmployeeData(empRecord, QueryData);//
//QueryData now contains the data you want your original object to contain
}
catch (Exception ex)
{
LogAppError(ex.ToString());
}
} //when this function terminates, QueryData ceases to exist.
In order to fix it, pass the employee by reference (use the ref keyword) instead of passing it by value, which is what you're doing right now.