|
Here is a question regarding best coding practices involving exceptions
Scenario:
You are the developer of .NET components to be used by other developers in creating enterprise applications. You have been tasked to build a widget value calculator.
As is well-known in the widget industry, widget value is a function of weight. You are ready to engage your development skills in developing a spectacular widget value calculator, however, knowing nothing about how or where your function will be used, not to mention the capabilities of the developers who will use it, you are vexed by one simple question: how to handle the situation where a user of your function sends a meaningless input to the function, which, in the case of widgets, would be a negative weight.
You recognize that there are basically two options:
A) throw an exception whenever a negative weight is supplied to your function, or,
B) do not throw an exception, but use a return object or property to indicate that an invalid argument was supplied, and set the actual return value to zero.
You know that, if you choose option A, your component may crash the application if the developer of that application did not anticipate and handle potential exceptions. You are also aware that, if you use a return object or property to indicate a problem WITHOUT throwing an exception, the developer using your function might forget to check that value and continue processing with bad or missing data.
You understand the implications of exception usage and handling, you believe in good coding practices, and you want to build a superior product. Which option do you choose?
This has been the topic of a week-long, heated debate in our group. We all have very strong opinions for option A or B. Seriously, any input is appreciated. Please do not hold back in expressing your opinion on this!
Don Boinske
|
|
|
|
|
Follow the Design by Contract Model for exception.
http://www.codeproject.com/csharp/designbycontract.asp
|
|
|
|
|
I strongly prefer A.
Better fail the application that return wrong data (okay this may lead to rocket explosions though - Arian ?)
If you throw an exception then you will detect that something went wrong, whereas the not checked return value may be missed.
Furthermore, in my opinion the use of exception handling for this kind of "logic" leads to easier code (in understanding and maintaining).
And a side note to the post above (using contracts like in Eiffel): you will get the error in development but not in production because you normally turn off input validation to gain performance (at least this was what Bertrand Meyer tells in his lectures).
Therefore A and A again
-^-^-^-^-^-^-^-^-^-^-^-
no code is free of bugs
|
|
|
|
|
boinske wrote: A) throw an exception whenever a negative weight is supplied to your function
Might I suggest an ArgumentOutOfRangeException[^] for this.
boinske wrote: B) do not throw an exception, but use a return object or property to indicate that an invalid argument was supplied, and set the actual return value to zero.
No. The caller should be aware of the range of permitted arguments therefore any argument that is not valid should be rejected with an exception. It is an exceptional circumstance that the method receives an out of range argument.
boinske wrote: You know that, if you choose option A, your component may crash the application if the developer of that application did not anticipate and handle potential exceptions.
Not your problem. If the developer using the component isn't keeping within the defined parameters then that is their fault. The .NET Framework throws exceptions all the time. What do you do with them? You either fix the problem that caused the exception or handle them in a catch block somewhere.
Just make sure that the limits are clearly documented and the exception message explains what went wrong.
boinske wrote: This has been the topic of a week-long, heated debate in our group. We all have very strong opinions for option A or B. Seriously, any input is appreciated. Please do not hold back in expressing your opinion on this!
It shouldn't be the subject of a heated debate. The answer is a no brainer. Use exceptions. There is even an exception in the framework for this.
I should stress that regardless of what option you choose you WILL be blamed for bugs and errors that are not yours. With exceptions you at least have the opportunity to deflect some of that by indicating in the exception message what caused the problem.
|
|
|
|
|
Colin makes excellent points, and I want to add to them.
If you rely on return statuses, then you have introduced a weakness into the system whereby further processing can be performed on values from your widget because the system consuming your widget has chosen to ignore statuses. Return values tended to be used by systems that existed before SEH (structured exception handling).
One argument that you will sometimes hear is that you can do the same as above by wrapping the code in a try/catch block and then ignore the fact that you received an error and continue processing with incorrect values. This is true, but misses the point that the developer has chosen to ignore the exception. They are aware it exists, but they are doing nothing with it - this is a deliberate choice and not an omission.
The simple fact is - an exception exists to show that something Exceptional has occurred (i.e. something outside the norm). If your inputs don't conform to expected values, then this is Exceptional processing.
One thing that hasn't been mentioned is testing. It's reasonable to assume that people who are using your component perform their own testing. As long as you've documented the conditions that can lead to the exceptions, then you give the consumers of the component a chance to develop their own tests. It can help to give them a hint as to areas where their code might go wrong.
Deja View - the feeling that you've seen this post before.
|
|
|
|
|
I would delegate the decision to the application developer (he/her is your customer). You can add a boolean property ("throw" or "return"), and set the default to "throw".
Regards
|
|
|
|
|
A is best, every time.
But if your function uses integers (rather than floating point values) use unsigned types and avoid that whole problem altogether.
|
|
|
|
|
Hi,
I'm having real problems getting my MSBuild script to work. I've got various projects that all need to be built (in the correct order as there are various project references)
I'm trying to write a build script to build all the projects, and output the binaries to a single location.
I'm trying to use the MSBuild task to build all the project files. But if I just specify all the project files, the dependancies don't exist and it won't build. So I split it up into a seperate target for each project. I had hoped each target would build the required project, copy the binaries to the common directory, and then the next project could reference the already built binary (using the referencepath property of the msbuild task). Problem is that the Copy task doesn't seem to copy the files, It's as if the MSBuild task doesn't actually write out the binaries until after the copy task has run, because if I run the build again, the copy works fine, it just never works the first time when there are no binaries to start with.
This is what i've got so far:
<Project DefaultTargets="BuildAll" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ProjectLibrary Include="C:\Source\Library\Library.csproj"></ProjectLibrary>
<ProjectFramework Include="C:\Source\Framework\Framework.csproj"></ProjectFramework>
</ItemGroup>
<PropertyGroup>
<Configuration>Release</Configuration>
<DestFolder>Deployment\</DestFolder>
</PropertyGroup>
<ItemGroup>
<ProjectLibraryOutputFiles Include="C:\Source\Library\bin\$(Configuration)\*.*"></ProjectLibraryOutputFiles>
<ProjectFrameworkOutputFiles Include="C:\Source\Framework\bin\$(Configuration)\*.*"></ProjectFrameworkOutputFiles>
</ItemGroup>
<Target Name="LibraryBuild">
<MSBuild Projects="@(ProjectLibrary)" ContinueOnError ="false" Properties="Configuration=$(Configuration);ReferencePath=C:\Build\Deployment">
</MSBuild>
<Copy SourceFiles="@(ProjectLibraryOutputFiles)" DestinationFolder="$(DestFolder)"></Copy>
</Target>
<Target Name="FrameworkBuild" DependsOnTargets="LibraryBuild">
<MSBuild Projects="@(ProjectFramework)" ContinueOnError ="false" Properties="Configuration=$(Configuration);ReferencePath=C:\Build\Deployment">
</MSBuild>
<Copy SourceFiles="@(ProjectFrameworkOutputFiles)" DestinationFolder="$(DestFolder)"></Copy>
</Target>
<PropertyGroup>
<BuildAllDependsOn>FrameworkBuild</BuildAllDependsOn>
</PropertyGroup>
<Target Name="BuildAll" DependsOnTargets="$(BuildAllDependsOn)"/>
</Project>
I've also tries putting the copy task in a seperate target, but that doesn't work. I've tried using this "<Output ItemName="OutputFiles" TaskParameter="TargetOutputs"/>" in the MSBuild task, but that only produces a list of the binaries, which is no good as I also want the .pdb/.config and various other supporting files to be copied.
I've looked all over for how to achive this, but I can't find anything. Can anybody point me to a good resource, or templates for building multiple projects with a MSBuild Script (I was using the example from this page, but it doesn't deal with references between the projects or copying the non binary files http://www.sedodream.com/PermaLink,guid,ed3a0c98-fdac-4467-9116-5b3bf6755abc.aspx)
Thanks
Simon
|
|
|
|
|
MSBuild might not be your easiest option for this. Have you looked at NAnt instead? I think it's a lot easier to work with than MSBuild.
|
|
|
|
|
Thanks.
I Did consider that for a while, but i'm going to stay with MSBuild for now as i've solved the problem.
(For anyone else with similer issues. The problem was that the output files item groups are populated first. So when the build occurs, the files then exist, but they aren't in the item groups. To fix the issue, you need to make a list that isn't populated until after the build has occured. So create a target for coping the files, and include a createItem task in it to create a list of the files. This will now contain the full list of files provided the task is run after the build occurs.
<CreateItem Include="C:\HGT Source\dotNetDevelopment\Library\Hadley.Library\bin\$(Configuration)\*.*">
<Output ItemName="ProjectLibraryOutputFiles" TaskParameter="Include"></Output>
</CreateItem>
Easy
Simon
|
|
|
|
|
If anyone could point me in the right direction, I would be very grateful.
I have a main form, which shows other smaller forms. These forms must always be on top of the main form, but not on top of other forms. Similar to the tool windows in photoshop. Obviously a TopMost form is not the right choice here.
I am not wanting to use MDI child windows.
Any ideas?
www.wickedorange.com
www.andrewvos.com
|
|
|
|
|
AFAIK that is exactly what Form.Owner does
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- use PRE tags to preserve formatting when showing multi-line code snippets
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Whoa.
Thanks alot! Can't believe I didn't know that was there!
I guess I get to delete all those api declares now
www.wickedorange.com
www.andrewvos.com
|
|
|
|
|
Hi
I am having some issues with installation / deployment of a vb.net project, which are because of some OCM & Activex components
- I had originally made most of the application in vb6
- Then we converted the codes to vb.2005 express
- Then some more development was done
- Now the issue is that when we try to install the application on a client’s machine (which dose not have VB6 installed), the application dose not work
- After investing some time we found out that the issue is due to non availability of vb6 COM & Activex components
How do we add the reference of these COM component to the setup and export the DLL’s with it
Regards
Nishkarsh
-- modified at 6:10 Tuesday 13th November, 2007
|
|
|
|
|
Please don't put the phrase "need urgent help" in your message. It is rather rude.
"Any sort of work in VB6 is bound to provide several WTF moments." - Christian Graus
|
|
|
|
|
nishkarsh_k wrote: Hi
I am having some issues with installation / deployment of a vb.net project, which are because of some OCM & Activex components
- I had originally made most of the application in vb6
- Then we converted the codes to vb.2005 express
- Then some more development was done
- Now the issue is that when we try to install the application on a client’s machine (which dose not have VB6 installed), the application dose not work
- After investing some time we found out that the issue is due to non availability of vb6 COM & Activex components
How do we add the reference of these COM component to the setup and export the DLL’s with it
What you need to do is to either manually register the OCX / ActiveX components using regsvr32 command from the command line, OR an even easier solution would be to create an Installer in Visual Studio 2005 by creating a "Setup and Deployment Project", and adding the corresponding EXE and DLL to the install project. The Setup and Deployment essentially registers the ActiveX DLLs on the client machine, which is the same thing as registering them manually. Of course if you do register them manually you have to first copy the libraries onto the client machine manually and then try to register. Hope this helps.
Pete Soheil
DigiOz Multimedia
http://www.digioz.com
|
|
|
|
|
I am trying to use an impersonation to access a remote system network share using the credentials that are created on the remote system. The remote system is on the different domain.
I am able to use the following route to secure access through Windows -> Map Network Drive:
1) IPAddressOfTargetSystem\ShareName,
2) FullyQualifiedSystemName\ShareName
3) In the connect as I gave the IPAddressOfTargetSystem\Username or FullyQualifiedSystemName\Username and password. It worked.
Programmatically, when I tried using LogonUser, all of the combinations are failing:
1) If the domain name is empty or NULL or "", then the call does not seem to get processed at all.
2) I also tried to do a quick research with this article (http://www.codeproject.com/csharp/cpimpersonation1.asp?msg=2191661#xx2191661xx[^]) but in the specific post, (mirh) seems to be explain about something on 'Mirrored Accounts'. What is that? Would it solve the problem?
|
|
|
|
|
Hi I have developed a project in vb6 and converted it to vb.net 2005 Express edition, fixed the issues after conversion, also did some more development wok.
Now after completion of the when I built a release I am not able to install it on client’s place. Tried running application from the exe n debug folder by coping the entire folder on the clients machine but it refused to work..
What I am suspecting is that there is some dependencies from VB6 installation but I am not able to figure it out
I installed VB6 on clients machine.. Now the application works fine.. This proves that there is some dependencies from VB6
What should I do?
|
|
|
|
|
I think that your converted project has some COM references that are located under System32 or something.. When you are building the setup, ensure that all required dlls (from both BIN folder and other folder that you have referenced) are added in your setup file..
Thanks and Regards,
Michael Sync ( Blog: http://michaelsync.net)
"Please vote to let me (and others) know if this answer helped you or not. A 5 vote tells people that your question has been answered successfully and that I've pitched it at just the right level. Thanks."
|
|
|
|
|
ye i have some com objects in my project... and that is exactly what is causing the issue...
I checked for the .dll in bin and other places, i did not found any one except "My Project.Resources.Designer.vb.dll" not included...
One more thing i observed that all the dll are present in bin, debug and release folders, only the above mentioned one is not present in bin..
can u please help me out... with more info..
regards
Nishkarsh
|
|
|
|
|
Hi All,
I am getting this following error while using odb.net provider for .net while connecting tith oracle.
My application is a windows based application.. Can anyone tell me the exact reason for this error and give me a solution on how to rectify this error..
<b> Unable to load DLL 'OraOps9.dll': The specified procedure could not be found. (Exception from HRESULT: 0x8007007F)</b>
Advance Thanks,
Umashanker.k
|
|
|
|
|
umashankergr8 wrote: Can anyone tell me the exact reason for this error and give me a solution on how to rectify this error
I'm going to go out on a limb here and suggest that the reason for this is because it can't find the DLL OraOps9.dll. Either you don't have it installed, or it's installed somewhere that your application can't see it (i.e. not in the PATH). Search for it on your machine to find out if it's installed, and if it isn't install it. If it is installed, check your PATH settings.
Deja View - the feeling that you've seen this post before.
|
|
|
|
|
|
Hello,
I works on SSIS integration services and i business Developpement Studio.
When i use a wizard i can check delete or append row for destination table.
My problem is: I don't find this both options when i open my dtsx package in Visual Studio.
thanks for your help.
|
|
|
|
|
Hi
I'm new to Visual C++ and .NET Framework; I'm trying to display a bitmap image on a Windows Form in Visual Studio 2005 but am experiencing problems with this.
I have examples for VS 2003 but these don’t seem to work in VS 2005.
Does anyone have any examples of displaying a bitmap in VS 2005?
Any help appreciated
|
|
|
|