I have a C# function that does some processing and needs to return figures about what it has processed, success, failure, etc.
Can anyone tell me if there are any standard framework classes that will handle this (for example, number of records processed, number successful, failed, etc) ?
Alternatively, can anyone say how they usually handle this? Is the best way to create a class, or to use out parameters?
I don't think there is any standard class for representing this kind of information. The best way to handle this is probably to define your own class. In C# 3.0, you can use automatically implemented properties, which reduce the amount of code you need to write:
class Results {
public double Sum { get; set; }
public double Count { get; set; }
}
I think out parameters should be used only in relatively limited scenarios such as when defining methods similar to Int32.TryParse and similar.
Alternatively, if you need to use this only locally (e.g. call the function from only one place, so it is not worth declaring a new class to hold the results), you could use the Tuple<..> class in .NET 4.0. It allows you to group values of several different types. For example Tuple<double, double, double> would have properties Item1 ... Item3 of types double that you can use to store individual results (this will make the code less readable, so that's why it is useable only locally).
I don't think there is any built in classes for that. Usually I will create my own class to accommodate the kind of result you were talking about, and yes, I prefer a Result class instead of out parameters simply because I feel it's cleaner and I'm not forced to prepare variables and type in the out parameters every time I need to call that function.
I don't know if there is an known framework to do this but it's a common practice in all the new projects I'm involved now.
It looks like as a good practice to have a custom result class in order to give the method executor the proper results and/or result object.
Simple generic result class:
public partial class GenericResult
{
public IList<string> Errors { get; set; }
decimal Value { get; set; }
public GenericResult()
{
this.Errors = new List<string>();
}
public bool Success
{
get { return (this.Errors.Count == 0); }
}
public void AddError(string error)
{
this.Errors.Add(error);
}
}
A method that uses previous class as the return type:
public GenericResult CanDivideNumber(int a, int b)
{
GenericResult result = new GenericResult();
try
{
result.Value = a / b;
}
catch (Exception ex)
{
result.AddError(ex.ToString());
}
return result;
}
Usage example:
var result = CanDivideNumber(1, 0);
// Was the operation a success?
// result.Success
// Need to get error details?
// result.Errors
// The processing result?
// result.Value
11 years later, I can say that is is best to adopt the Result pattern with a result class if you are going this route. Using Tuple Task<Tuple<Status, T>> where Status might be an enum {Success,Failure,Exception} and T is a generic type for data returned works decently, but is a little less readable than implementing and returning a Result class.
Now, you still get into Task<Result<T1,T2,T3,T4,...>> expansion with Result having an embedded Status enum. Personally, I like to still have try-catch blocks that log/report my errors and suppress them. I then bubble up the result to, in my case, a controller where status codes are properly returned.
I don't think there is anything standard that will do this for you.
A great example of using out parameters, is the TryParse functions.
If you have two values to return, use one as the return value and one as an out parameter.
If you have any more, create your own return value class and return that.
Related
Consider the following code:
public interface IIdentifiable<T>
{
T Id { get; set; }
}
public interface IViewModel
{
}
public class MyViewModel1 : IViewModel, IIdentifiable<int>
{
public string MyProperty { get; set; }
public int Id { get; set; }
}
public class MyViewModel2 : IViewModel, IIdentifiable<string>
{
public string MyProperty { get; set; }
public string Id { get; set; }
}
I also have class that operates with ViewModels:
public class Loader<T> where T: IViewModel
{
public void LoadData()
{
/*some important stuff here*/
if (typeof(IIdentifiable<??>).IsAssignableFrom(typeof(T)))
{ // ^- here's the first problem
data = data.Where(d => _dataSource.All(ds => ((IIdentifiable<??>) ds).Id != ((IIdentifiable<??>) d).Id)).ToList();
} // ^---- and there the second ----^
/*some important stuff here too*/
}
}
Now, as you can see, viewmodels that I have might implement the IIdentifiable<> interface. I want to check that, and if it's true,
I want to make sure my data list does not contains any entry that are already present in my _dataSourse list.
So I have 2 questions:
I don't know what IIdentifiable<> has in its generic parentheses, it might be int, string or even GUID.
I tried typeof(IIdentifiable<>).IsAssignableFrom(typeof(T)) which is the correct syntax, yet it always returns false.
Is there a way to check whether T is IIdentifiable<> without knowing the exact generic type?
If there is an answer for the first question, I would also like to know how can I compare the Id fields without knowing their type.
I found this answer quite useful, yet it doesn't cover my
specific case.
I know that I probably can solve that problem if I make my Loader<T> class a generic for two types Loader<T,K>, where K would be the
type in IIdentifiable<>, yet I would like to know if there are other solutions.
P.S. In addition to my first question: I'm also curious why one can write something like this typeof(IIdentifiable<>).IsAssignableFrom(typeof(T)) if it returns false when the generic type of IIdentifiable<> is not specified?
Edit: I guess, in hindsight, I understand why I can't write the code this bluntly - because there's might be the collection ICollection<IViewModel> where the entries implement different types of IIdentifiable<> (or don't implement it at all), and the check like that would fail awkwardly. Yet maybe there is a way to do something like that with some restrictions, but without creating second generic parameter to my Loader?
Try add two methods to your Loader<T>:
public bool CanCast<TId>()
{
var identifiableT = typeof(IIdentifiable<>).MakeGenericType(typeof(TId));
return identifiableT.IsAssignableFrom(typeof(T));
}
public IEnumerable<IIdentifiable<TId>> Filter<TId>(IEnumerable<T> data)
{
return data.Where(d => _dataSource.All(
ds => !((IIdentifiable<TId>) ds).Id.Equals(((IIdentifiable<TId>) d).Id)));
}
Then in LoadData
if (CanCast<int>())
data = Filter<int>(data);
else if (CanCast<Guid>())
data = Filter<Guid>(data);
// and so om
Well, I would suggest you to always use a string for identification. You can convert int and guid to a string. And if you want to ensure proper type is used then you can prefix the string with type information.
However, I do think that the performance of you algorithm would be very poor as you wouls essentially loop 2 containers so it would be O(n * m).
Thus it would be best to either do appropriate SQL query if both sources are from the database or use a dictionary if you do it in code. Alternatively if data is properly sorted, you could find duplicates more efficiently.
By the way generics are quite limited in C#. Sometime using ˋFunc<>ˋ could help but even then you have to provide extra information to the algorithm.
We should address your question in two steps (because there really are two problems to solve here).
First, make following change to your interface IIdentifiable<T>
public interface IIdentifiable<T>
where T : IEquatable<T>
{
T Id { get; set; }
}
This will ensure that you can compare Id properties correctly.
Secondly, in your LoadData() method, change the if statement to
if (T is IIdentifiable<T>)
{ // ^- here's the first problem
data = data.Where(d => _dataSource.All(ds => ((IIdentifiable<T) ds).Id != ((IIdentifiable<T) d).Id)).ToList();
}
I have a method with the following signature:
bool DoSomething();
I want to change it to this:
bool DoSomething(IList<int> newIDs);
The boolean and the list of IDs are not related to each other. The new method contains an extra output that contains the list of new IDs. Is this bad practice? What is the right way to return multiple values in this situation?
You could also "wrap" all the return values inside an object:
public class Payload
{
public List<int> NewIDs { get; set; }
public bool Status { get; set; }
}
//Use Payload class
public Payload DoSomething(...){...}
I think it's important to understand what the semantics of the returned values are before deciding on a specific pattern. If you edit your question with details, I'll provide more insight as well.
Cheers
There is a common pattern called the TryParse pattern that is used extensively within the C# Base Class Library which is basically the same as your function signature.
For example: DateTime.TryParse
public static bool TryParse(
string s,
out DateTime result
)
I think it is fine to use this provided you include the 'out' keyword.
Edit:
Also give the function a name that makes it clear why it returns a null.
I have an object that represents physics characteristics of some air tunnel:
public class Tunnel
{
public double Length { get; set; }
public double CrossSectionArea { get; set; }
public double AirDensity { get; set; }
public double Pressure { get; set; }
//...
}
I need to check correctness of parameters: for example, Length must be > 0, Pressure >= 0 and so on. The first idea was just to put checking to property accessor and throw exception on invalid data:
public class Tunnel
{
private double length;
public double Length
{
get { return length; }
set
{
if (value <= 0)
throw new TunnelParametersException("Invalid data");
length = value;
}
//...
}
But I have a collection of such object and it will be serialized/deserialized to/from XML-file. So the problem is that it will not work with serialization (if I'm not mistaken). User can edit file and enter whatever he want and I will not able to catch it.
So, as I understand, need to create some function (in Tunnel class or in another one) that I will call to check that all values are correct. But here another problem: Tunnel can have few invalid parameters. How should I return errors and process them? The program must return all found errors in one call. And this way is good for only my own use of classes. I probably can't obligate another programmer to use validation after every editing of data.
Give me please an advice how would be more correct to implement such checking of values and solve my problem - maybe some another flexible way so would be easy to manage and improve this code in the future. Thank you.
EDIT: Returning to my first idea, is there any way to validate data during or after serialization?
Simplest possible way:
//Returns empty list if no errors.
public List<TunnelErrors> Validate()
{
//Validate params
}
What comes into my mind is this.
I would keep a readonly IsValid property. On the getter I would do all my validation and say true or false.
In any place where I use the object I would would check to see if the object.IsValid is true.
try making your files pass through a wrapper function everytime, and making the files on disk read-only for normal user,i.e, if the user has to edit the file he does so only through your program, when the user is finished editing u pass all the data through your function to see if the whole data is still valid or not,
For the edit : make the serialization streams pass through a sort-of buffer function,that processes the data before serialization or during it, depending on which way is easier to implement, if you chose the former, the data will first be validated(the return type and parameter type will be same) and then be serialized, otherwise the data will be checked as it is converted..
I have a interface member like this.
AppInterface.cs
ObjLocation[] ArrayLocations { get; }
App.cs
public ObjLocation[] ArrayLocations
{
get
{
return **something**;
}
}
I dont know how to complete it, Or there is another way to implement the array members.
Then It can pass the compiler. thank you.
Well, you'd just return an array:
public ObjLocation[] ArrLocations
{
get
{
ObjLocation[] locations = new ObjLocation[10];
// Fill in values here
return locations;
}
}
Or if you've already got a List<ObjLocation>, you might do:
public ObjLocation[] ArrLocations
{
get
{
return locationList.ToArray();
}
}
It's hard to know what to suggest you write for the property body when we don't know what the property is meant to do or what data you have.
One thing you should consider very carefully is what happens if the caller changes the array contents. If you have an array within your class and you just return a reference to that, then the caller is able to mess with your data - which probably isn't what you want. There's no way of returning a "read only" array, because there's no such concept - which is one reason they're considered somewhat harmful. (It would be nicer if the interface specified that you had to return an IList<ObjLocation> or IEnumerable<ObjLocation>.)
If this isn't enough to solve your problem, please give more information.
return new ObjLocation[size] or return new ObjLocation[] { objLocationInstance1, objLocationInstance2, ... }
I have a class Employee. I want to be able to Validate() it before I save it to make sure all the fields have been populated with valid values.
The user of the class may call Validate() before they call Save() or they may call Save() directly and Save() will then call Validate() and probably throw an Exception if validation fails.
Now, my (main) question is this;
If my Validate() function returns a simple bool then how do I tell the user of the class what is wrong, i.e. "Email not filled in", "ID not unique" etc. For the purposes of this I just want the error strings to pass to the human user, but the principle is the same if I wanted a list of error codes (except that makes the use of a bitmap more logical).
I could use an Out paramater in my Validate function but I understand this is frowned upon.
Rather than returning a bool, I could return a string array from my function and just test if it was empty (meaning no errors) - but that seems messy and not right.
I could create a Struct just to return from this method, including a bool and a string array with error messages, but just seems clunky.
I could return a bitmap of error codes instead of a bool and look it up, but that seems rather excessive.
I could create a public property "ValidationErrors" on the object which would hold the errors. However, that would rely on me calling Validate() before reading it or explicitly calling Validate from the Property() which is a bit wasteful.
My specific program is in C# but this looks like a fairly generic "best practice" question and one I am sure I should know the answer to. Any advice gratefully received.
I could create a Struct just to return from this method, including a bool and a string array with error messages, but just seems clunky.
Why does it seem clunky? Creating an appropriate type to encapsulate the information is perfect. I wouldn't necessarily use a string to encode such information, though. An enum may be better suited.
An alternative would be to subclass the return type and provide an extra child class for every case – if this is appropriate. If more than one failures may be signalled, an array is fine. But I would encapsulate this in an own type as well.
The general pattern could look like this:
class ValidationInfo {
public bool Valid { get; private set; }
public IEnumerable<Failure> Failures { get; private set; }
}
I would probably go for the bitmap-option. Simply
[Flags]
public enum ValidationError {
None = 0,
SomeError = 1,
OtherError = 2,
ThirdError = 4
}
...and in the calling code, simply:
ValidationError errCode = employee.Validate();
if(errCode != ValidationError.None) {
// Do something
}
Seems nice and compact to me.
I would follow the pattern of the TryParse methods and use a method with this signature:
public bool TryValidate(out IEnumerable<string> errors) { ... }
Another option is to pull the validation code out of the object into its own class, possibly building on the Specification pattern.
public class EmployeeValidator
{
public bool IsSatisfiedBy(Employee candidate)
{
//validate and populate Errors
}
public IEnumerable<string> Errors { get; private set; }
}
I have found it a good approach to simply have a method (or a property, since C# has nice support for that) which returns all validation error messages in some kind of sensible, easy to use format, such as a list of strings.
This way you can also keep your validate method returning bools.
Sounds like you need a generic class:
public sealed class ValidationResult<T>
{
private readonly bool _valid; // could do an enum {Invalid, Warning, Valid}
private readonly T _result;
private readonly List<ValidationMessage> _messages;
public ValidationResult(T result) { _valid = true; _result = result; _messages = /* empty list */; }
public static ValidationResult<T> Error(IEnumerable<ValidationMessage> messages)
{
_valid = false;
_result = default(T);
_messages = messages.ToList();
}
public bool IsValid { get { return _valid; } }
public T Result { get { if(!_valid) throw new InvalidOperationException(); return _result; } }
public IEnumerable<ValidationMessage> Messages { get { return _messages; } } // or ReadOnlyCollection<ValidationMessage> might be better return type
// desirable things: implicit conversion from T
// an overload for the Error factory method that takes params ValidationMessage[]
// whatever other goodies you want
// DataContract, Serializable attributes to make this go over the wire
}
You could take a look at Rockford Lhotka's CSLA which has extensive business rule/validation tracking forr business objects in it.
www.lhotka.net
I agree with Chris W. I asked the same questions, before reading Rocky`s Expert C# Business Objects.
He has a brilliant way of handling business validation rules. The validation is done after each property is set. Whenever a rule is broken, the object`s state become InValid.
Your business class can implement the IDataError interface. Binding your UI controls to your business object properties will then notify your ErrorProvider control of any broken rules on your object.
I would really recommend you take the time and look at the validation section.
We are using spring validation together with an Windows Forms error provider.
So our validation function returns a dictionary with a control id and an error message (for every validation error). The error provider shows the error message in a pop up field near the control which caused the error.
I used some other validation schemes in the past - but this one works really well.