Generic property disadvantages? - c#

i use generic properties on my project,but i dont know,is there any disadvantage use them,please tell me a scenario,they have a disadvantage?my part of code below.
public class GenericResult<T>
{
public T Data { get; set; }
public bool IsSuccess { get; set; }
public string Message { get; set; }
}
public GenericResult<int> AddCategory(TCategory tCategory)
{
GenericResult<int> result = new GenericResult<int>();
//business logic validation,dont make sense,only example :)
if (tCategory.Name.Lenght > 100)
{
result.IsSuccess = false;
result.Message = "Category Name length is too long";
result.Data = 0;
}
//handle .net runtime error//may be database is not aviable.
try
{
result.Data = this.catalogRepository.AddCategory(tCategory);
result.IsSuccess = true;
}
catch (Exception ex)
{
result.Data = 0;
result.IsSuccess = false;
result.Message = ex.Message;
}
return result;
}
public GenericResult<IEnumerable<TCategory>> GetCategoryHierarchy(TCategory parentCategory)
{
GenericResult<IEnumerable<TCategory>> result = new GenericResult<IEnumerable<TCategory>>();
try
{
IEnumerable<TCategory> allCategories = catalogRepository.GetAllCategories();
result.Data = GetCategoryHierarchy(allCategories, parentCategory);
result.IsSuccess = true;
}
catch (Exception ex)
{
result.IsSuccess = false;
result.Data = null;
result.Message = ex.Message;
}
return result;
}

If you don't want to throw an exception but prefer to return a result containing either the error or the value i.e. a MayBe that's fine in some situations. But to be honest in this situation I'd prefer simply throwing/passing through the exception.
I'd prefer returning an immutable struct as MayBe instead of a mutable class like you did. It's very similar to Nullable<T>, except it works on reference types and can store an error. Something like:
public struct MayBe<T>
{
private T value;
private Exception error;
public bool HasValue{get{return error==null;}}
public T Value
{
if(error!=null)
throw error;
else
return value;
}
public static MayBe<T> CreateError(Exception exception)
{
return new MayBe<T>(default(T),exception);
}
public static MayBe<T> CreateValue(T value)
{
return new MayBe<T>(value,null);
}
public static implicit operator MayBe<T>(T value)
{
return CreateValue(value);
}
public override string ToString()
{
if(HasValue)
return "Value: "+Value.ToString();
else
return "Error: "+Error.GetType().Name+" "+Error.Message;
}
}
Your code becomes
public MayBe<int> AddCategory(TCategory tCategory)
{
try
{
return this.catalogRepository.AddCategory(tCategory);
}
catch (Exception ex)
{
return MayBe<int>.CreateError(ex);
}
return result;
}
public MayBe<IEnumerable<TCategory>> GetCategoryHierarchy(TCategory parentCategory)
{
try
{
IEnumerable<TCategory> allCategories = catalogRepository.GetAllCategories();
return allCategories;
}
catch (Exception ex)
{
return MayBe<int>.CreateError(ex);
}
return result;
}
One problem I see with this implementation is that exceptions are not completely immutable. That can cause problems if the same MayBe<T> throws on multiple threads. Perhaps someone can suggest a better implementation.

I'd rather removing IsSuccess and Message and returning only the object. See below...
Take a look at my question Good practices when handling Exceptions in C#. You're returning errors instead of throwing exceptions, and in .NET, that's not suggested.
From MSDN:
Do not return error codes. Exceptions are the primary means of reporting errors in frameworks.
What you are doing is suggested in some articles/books I've read, including The Pragmatic Programmer: From Journeyman to Master and this Joel Spolsky article, but as said by MSDN, in .NET exceptions are better for this purpose.
Edit:
If you still want to do it that way (even if that could bring some problems to developers that are working with your code), I think that, in general, it could be a good way. In fact, I'm going to edit the question I linked on this answer to place a link to your code for an alternative of returning errors instead of throwing Exceptions in .NET

If your application scope is completely inside .NET scope, then this pattern is of no use and just as others have mentioned, you should let exceptions be thrown and you might want to change the exceptions.
However, if your application scope is wide that might include any other client side framework, probably via JSON, web services etc, and if client side framework does not properly support exceptions then this pattern may be useful. For example, in JSON based Javascript call, you will always expect a result, and a message indicating a failure on server side or not. Failure on client side could be either failure on server side or network failure, usually all client framework will detect and only report network failures and improperly coded framework will lead to chaos when you will not get any error report on client side of what exactly failed on server side.
One more place this pattern is very useful is, when you are writing some plugin in the UI or inside someone else's framework where just throwing exceptions can result in undesired results as after having exceptions, third party framework may say "Unexpected error" as they do not and they are not made to understand your exceptions. This pattern is useful while being inside someone else's framework and still letting underlying framework work correctly regardless of your failure. And you probably can communicate correctly within your app framework.
I recently have seen, and its still a bug, WPF stops processing some pending UI related activities if you set a source of an image that is a web address and that does not exist. You will see a network related exception traced, but WPF will incompletely stop processing anything that was in pending tasks and app still works but it does affect other UI elements where it should not.

The use of the automatic property is quite fine and I do not see any issues.
But I strongly discourge the pattern using a class as a result to tell the outside world that something failed. Return null or throw an exception when something badly fails.
hth
Mario

Related

How to send function parameters of fucntion in exception

I realized that the app I am working on generate quite a few errors. Pretty much everytime an error happens it's caught and logged, but sadly, none of them log the values that were sent (that would be useful to debug).
Is there an easy solution that I could add to also send all parameters of through the log?
Here's an example of what I have.
public static async Task<InventoryItem> GetTaskInventory(string labeladresse)
{
InventoryItem result = null;
await Task.Run(() =>
{
try
{
IDeliveryService client = Common.GetDeliveryService();
result = client.GetLineTaskInventory(labeladresse);
}
catch (Exception ex)
{
ex.Data.Add("parameters", $"labeladresse = {labeladresse}");
LogError(ex);
}
finally
{
}
}).ConfigureAwait(false); ;
return result;
}
But I would like to change the ex.Data.Add part to something more generic, since I'm probably going to put it quite often, I'd like to be able to use a line I can more copy paste where needed.
Imagine something like: ex.Data.Add(function.parameters[]);
Thank you and have a nice day

WCF really wierd and unexpected behavior

I have this WCF Service Application which contains 10-15 services. the services generally serve the same purpose but have different implementations. There was this one really simple method which was part of the soap service. The method basically looked like this
public Data GetData(string param1, string param2, string checksum)
{
try
{
if (Utilities.StringsAreEmpty(param1, param2, checksum)
{
throw new FaultException<ServiceFault>(){ ErrorCode = 1 };
}
var caller = Repository.GetProviders(param1);
if (caller == null)
{
throw new FaultException<ServiceFault>(){ ErrorCode = 2 };
}
var realChecksum = Utilities.CalculateSha256Hash(string.Format("{0}{1}{2}", param1, param2, caller.Key));
if (realChecksum != checksum)
{
throw new FaultException<ServiceFault>(){ ErrorCode = 3 };
}
var data = Repository.GetData(param2);
return data;
}
catch (Exception ex)
{
LogException(ex);
throw new FaultException<ServiceFault>(){ ErrorCode = 99 };
}
}
The method shown above worked perfectly, just as expected. after some time I had to modify some other service and after doing that and publishing the changes to the server (all those services are build into one .dll assembly So they cannot be deployed partially) this particular method started to behave really weirdly. I was not seeing any errors in Log and the method itself did not return anything at all. now first thing I did was removed try catch block, (I had this kind of problem before and removing try catch helped), and magically everything started working again. Now, I don't really see any problem in here and since I had this kind of issue for the second time now I am really concerned about it. Can somebody explain why does try catch removal work here ? first time I had this problem the internal server error occurred and the response from the server was absolutely nothing. not even an error HTML (returned by wcf) or anything like that. is this some kind of a bug with WCF ? or is it supposed to work this way ? if so, how can that be avoided ?

rewriting recursive form to iterative. exception handling

Consider such a function:
void RequestThings(List<Things> container, Connection connection, Int32 lastVersion) {
var version = lastVersion;
try {
foreach(var thing in connection.RequestThings(version)) {
container.Add(thing);
version = thing.lastVersion;
}
}
catch(Exception ex) {
RequestThings(container, connection, version + 1);
}
}
But this choice is far not perfect: it involves adding to a recursion depth (up to a stack overflow) in case if there are (many) exceptions.
How do I rewrite this the iterative way?
I've tried to do this like:
var container = new List<Things>();
var version = getLastVersionFromDB();
foreach(var thing in connection.RequestThings(version)) {
try {
container.Add(thing);
}
catch(Exception ex) {
continue;
}
}
But it appears that exception doesn't get handled. How do I do this?
edit. the details
Connection.RequestThings(Int32 startVersion) requests data from a remote server. Accepts a seed version as its only parameter. There might be blocked/damaged documents which you cannot request though they appear on the results returned by calls to Connection.RequestThings(Int32 startVersion). This piece throws the exception
Don't know why but the inner try/catch in my iterative example doesn't catch the exception.
Generally, it's a bad idea to have a catch clause for all exceptions. Consider catching only a specific exception type to be sure that you're not swallowing unexpected errors.
Additionally, if you got a stack overflow in the first place, it indicates that you might be doing something wrong. For example, what happens if you pass an invalid version number to this method, and there are no documents with a larger version number available? This method will keep running forever, with no chance to gracefully cancel it. Especially since it seems that you are getting the "last version" from a database somehow; if this fails, you can be pretty certain that no higher version exists.
Having said that, you can simplify the method by creating an "infinite" loop and then using return to exit the method on success:
void RequestThings(List<Things> container, Connection conn, int version)
{
while (true)
{
try
{
foreach (var thing in connection.RequestThings(version))
{
container.Add(thing);
version = thing.lastVersion;
}
return;
}
catch (Exception ex)
{
Log.Error(ex);
version++;
}
}
}
A slightly better approach might be to make sure that you really get the entire list on success, or nothing. The way your code is written right now leaves the possibility of container being filled multiple times if an exception happens while iterating.
List<Things> RequestThings(Connection conn, int version)
{
while (true)
{
try
{
// this will either create an entire list,
// or fail completely
return connection.RequestThings(version).ToList();
}
catch (Exception ex)
{
Log.Error(ex);
version++;
}
}
}

What are best practices for handling exceptions in C#?

I have following code in my web page:
btnTest_Click(object sender, EventArgs e)
{
...
bool ret=myFunc(...);
if (ret)
{...}
else
{
lblStatus.Text="Some Text";
lblStatus.Visible=true;
}
}
private bool myFunc(...)
{
bool ret=false;
try
{
...
ret=true;
}
catch (Exception ex)
{
lblStatus.Text="Other Text";
lblStatus.Visible=true;
}
return ret;
}
If an exception occurs in myFunc, the lblStatus always shows "Some Text" not "Other Text". That means the catch block in myFunc doesn't really mean anything. I wonder how to fix this code to handle the exception better?
update: maybe my example is not very good. But I main purpose is to ask best practices for exceptions handling between calling and being called functions.
Why is your called function setting the label text on exception and the caller setting it on success?
That's something of a mixed metaphor. Let one party be responsible for UI (separation of concerns) while the other is responsible for doing work. If you want your called function to be fault tolerant try something like this:
private bool myFunc(...)
{
bool ret ;
try
{
...
ret=true;
}
catch
{
ret = false ;
}
return ret;
}
Then your caller can do something like:
bool success = myFunc(...) ;
lblStatus.Text = success ? "Some Text" : "Other Text" ;
lblStatus.Visible = success ;
if ( success )
{
// do something useful
}
Your catch clause is doing a lot. It catches every exception and "forgets it" suppressing it to the rest of the call stack. This can be perfectly fine but i'll try to explain your options:
You usually have 3 options:
Do not care about exceptions and let code above you handle it
Care to log the exception and let it propagate
The exception has its meaning in a given context and should not be propagated (this is your scenario)
I use all of them.
Option 1
You can just implement your function and if an exception occurs then it means some fault occurred and you just want your application to fail (at least to a certain level)
Option 2
Some exception occurs and you'll want to do one of two (or even both)
log the error
change the exception to another one more meaningful to the caller
Option 3
The exception is expected and you know how to completely react to it. For instance, in your case, i tend to believe you do not care about the type of exception but want a "good default" by setting some controls to a given text.
conclusion
There are no silver bullets. Use the best option for each scenario.
Nevertheless catching and "suppressing" catch(Exception ex) is rare and if seen often it usually means bad programming.
It displays "Some Text" because, when an exception occurs in myFunc, it returns false. Then you go into the else block of the btnTest_Click method, where you set lblStatus.Text to "Some Text" again.
So, basically, you're setting the label's text to "Other text" and then to "Some Text".
The exception handling is just fine. The problem with your code is that you are putting the "Some Text" string in the label if the return value is false, and that is when there was an exception, so it will replace the message from the catch block.
Switch the cases:
if (ret) {
// it went well, so set the text
lblStatus.Text="Some Text";
lblStatus.Visible=true;
} else {
// an exception occured, so keep the text set by the catch block
}
This is a complex question so I will try to break it down
In terms of functions I would try to stick to the Single Responsibility Principal. It should do one, well defined thing.
Exceptions should be that, exceptional. It is then preferable to try not to incur exceptions but obviously to deal with them as and when. For example it is better to test a variable as being null before attempting to use it (which would throw an exception). Exceptions can be slow (especially if a lot are thrown)
I would say that the question of WHERE you handle the exception is down to whose responsibility the exception is. If myFunc were to access a remote server and return a status of true or false you'd expect it to handle its own IO exception. It would probably not handle (or rethrow) any parameter problems. This relates to point 1. It is the functions responsibility deal with the connection process, not to provide the correct parameters. Hiding certain exceptions can cause problems if other people (or a forgetful you) tries to use the code at a later date. For example in this myFunc which makes a connection, should you hide parameter exceptions you may not realise you have passed in bad parameters
If you want to be informed of encountering a specific type of error inside one of your functions, I'd recommend inheriting Exception and creating your own exception class. I'd put a try-catch block inside your btnTest_Click() handler, and then I'd look to catch your custom exception class. That way, you won't lose the opportunity to detect any errors happening inside your myFunc() function.
I usually setup an error handling system. Here's a simple way, but this can be wrapped up into a base class. I can show you that if you need.
List<string> _errors;
void init()
{
_errors = new List<string>();
}
protected void Page_Load(object sender, EventArgs e)
{
init();
}
btnTest_Click(object sender, EventArgs e)
{
...
var result = myFunc(...);
if (result)
{...}
else
{
if (_errors.Count > 0)
{
var sb = new StringBuilder("<ul>");
foreach (string err in _errors)
{
sb.AppendLine(string.Format("<li>{0}</li>", err));
}
sb.AppendLine("</ul>");
lblStatus.Text=sb.ToString();//Make this a Literal
}
}
}
private bool myFunc(...)
{
var result = true;
try
{
...
...
}
catch (Exception ex)
{
result = false;
_errors.Add(ex.Message);
}
return result;
}

Specifying that a function does not return in C#

Is there any way to tell the C# compiler that a function never returns? I'm running into the following problem. This is a boiled down version for simplicity.
public int myMethod()
{
try
{
return anythingHere();
}
catch
{
Environment.Exit(1); //or a function which always either calls Environment.Exit or throws an exception
}
}
'package.class.myMethod()' not all code paths return a value.
If not, is there a general way to frame this sort of thing other than inserting unreachable code? Having a 'return 0' or somesuch after the Exit just seems ridiculous to me. As far as I know there is no way that a function can return from an Environment.Exit call, so no return value is needed if that branch is taken (if it threw an exception the function still wouldn't need to have returned a value).
EDIT:
Maybe something like this?
public T MyExit<T>()
{
Environment.Exit(1);
return default(T);
}
Still not entirely satisfactory though.
C# does not support this.
In fact, it is impossible to do this in the general case.
Make the method void, and pass in an object that contains the 'anythingHere' type of information you need as an out type, so that it can be set, but the method itself won't actually return anything.
public void myMethod(out anythingObject)
{
try
{
anything = new anythingObject(stuff goes here);
}
catch
{
Environment.Exit(1); //or a function which always either calls Environment.Exit or throws an exception
}
}
I'm not sure if it's what you're looking for, but this would avoid unreachable code:
public int myMethod()
{
int retVal = 0;
try {
retVal = anythingHere();
} catch {
Environment.Exit(1);
}
return retVal;
}
It might be better to throw an exception than to call Environment.Exit. If someone else used your class, and their process suddenly shut down, they'd be pretty surprised. By throwing an exception you can at least explain why the problem happened.
At the top level entry point of your app (i.e., Main) you could then set up a global exception handler (AppDomain.UnhandledException) that handles all exceptions and calls Environment.Exit.
Make it a void, instead of an int.
public void myMethod(out int i)
{
try
{
i = anythingHere();
}
catch
{
Environment.Exit(1);
}
}

Categories