-
Apr 16th, 2024, 10:51 PM
#1
Thread Starter
Fanatic Member
Where to put general procedures in C#
I have some C# procedures that are needed in several forms in the project.
So I cannot put them in the code of a specific form.
Where do I put them?
In VB6, I could easily add these procedures in a bas module.
But, what is the equivalent of that in C#?
And how do I add it to the project?
And where (in what file) do I save it?
Also, what if there are some procedures that are so generic that all projects may need to call them?
Where do I put those ones?
Please advise.
Thanks.
-
Apr 16th, 2024, 11:50 PM
#2
Re: Where to put general procedures in C#
Basically everything in .NET is a class. Forms are classes, just like everything else. Just create one or more classes and put your methods there. You already use classes like that from the framework, e.g. the System.IO.File class for operations relating to files. If it makes sense to do so, you can declare you class and its members static and then you can use it without having to create an instance, exactly as you do with the System.IO.File and various other classes. For the record, VB.NET has modules that are implemented to work in basically the same way that modules do in VB6 but they compile to the same things as C# static classes.
-
Apr 17th, 2024, 08:31 AM
#3
Re: Where to put general procedures in C#
For example, let's assume in your VB6 application you had a module named Utilities that had a slugify method in it that turned plain text values into slugs. That might look something like this:
Code:
Module Utilities
Function Slugify(ByVal strInput As String) As String
Dim strSlug As String
Dim i As Integer
Dim chrCurrent As String
strSlug = LCase$(strInput)
For i = 1 To Len(strSlug)
chrCurrent = Mid$(strSlug, i, 1)
If (chrCurrent >= "a" And chrCurrent <= "z") Or (chrCurrent >= "0" And chrCurrent <= "9") Then
strSlug = strSlug & chrCurrent
ElseIf chrCurrent = " " Then
strSlug = strSlug & "-"
End If
Next i
Slugify = strSlug
End Function
End Module
Now whenever you needed to reference the code, you'd execute the following:
Code:
Dim slug As String
slug = Slugify("Hello World")
The C# equivalent would be to create a class and make your method static which allows you to reference the member by using the class name itself:
Code:
public partial class Utilities
{
[GeneratedRegex(@"[^a-z0-9\s-]")]
private static partial Regex RegexSlugifyMatchNonValidCharacters();
[GeneratedRegex(@"\s+")]
private static partial Regex RegexSlufigyMatchDuplicateSpaces();
[GeneratedRegex(@"\s")]
private static partial Regex RegexSlugifyMatchSingleSpaces();
[GeneratedRegex(@"-+")]
private static partial Regex RegexSlugifyMatchDuplicateHyphens();
public static string Slugify(string text)
{
var slug = text.ToLowerInvariant();
slug = RegexSlugifyMatchNonValidCharacters().Replace(slug, "");
slug = RegexSlufigyMatchDuplicateSpaces().Replace(slug, " ").Trim();
slug = RegexSlugifyMatchSingleSpaces().Replace(slug, "-");
slug = RegexSlugifyMatchDuplicateHyphens().Replace(slug, "-");
slug = slug.Trim('-');
return slug;
}
}
Now whenever you needed to reference the code, it'd look like this:
Code:
var slug = Utilities.Slugify("Hello World");
-
Apr 17th, 2024, 05:23 PM
#4
Re: Where to put general procedures in C#
I think jmcilhinney and dday9 have give good usfull answers but I thought I share a link for you that may also help while moving from VB6 to c# hope it may have you
https://www.vbmigration.com/white-pa...ation-partner/
-
Jul 8th, 2024, 11:29 AM
#5
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by jmcilhinney
Basically everything in .NET is a class. Forms are classes, just like everything else. Just create one or more classes and put your methods there. You already use classes like that from the framework, e.g. the System.IO.File class for operations relating to files. If it makes sense to do so, you can declare you class and its members static and then you can use it without having to create an instance, exactly as you do with the System.IO.File and various other classes. For the record, VB.NET has modules that are implemented to work in basically the same way that modules do in VB6 but they compile to the same things as C# static classes.
Thanks for your help.
I just tried to add a class to my solution/project.
It shows me this dialogue:
https://i.imgur.com/jiMyHaS.jpeg
It doesn't give me any option to save the new class in any location that I wish.
So, I have no other choice but to click "Add". After I click "Add", it adds the class and creates the corresponding file under the project (not even the solution)
I need to create the file under a totally separate folder.
I need to have a folder named D:\Dev\VCS\Common so that these kinds of common class modules would be stored in there so that all my solution/projects would access them.
In other words these classes must be common components of all my solution/projects.
How can I do that?
Also, if you look at that same dialogue again, it doesn't give me the option to choose an EXISTING class either.
It only lets me add a NEW class.
Please note that in VB6 when you add a bas module, the dialogue box in VB6 lts you add either an existing or a new bas module.
But, in C#, the dialogue box doesn't give you that option.
Lets say I add a common class and define some common methods in it and use them in a solution/project.
Then later, I will be developing another solution/project and that new solution/project will also need to access those same common routines.
So, how can I add that EXISTING class to the new solution/project?
Please help.
Thanks.
-
Jul 8th, 2024, 11:35 AM
#6
Re: Where to put general procedures in C#
You could simply create the file outside of Visual Studio, open it inside of Visual Studio to edit, and then when you wanted to add it to your project you would use the Add Existing Item option.
-
Jul 8th, 2024, 12:14 PM
#7
Re: Where to put general procedures in C#
Originally Posted by IliaPreston
Thanks for your help.
I just tried to add a class to my solution/project.
It shows me this dialogue:
https://i.imgur.com/jiMyHaS.jpeg
It doesn't give me any option to save the new class in any location that I wish.
Normally I would right click on the relevant folder in solution explorer, select new, and theat way the item is created in the correct location.
Originally Posted by IliaPreston
So, I have no other choice but to click "Add". After I click "Add", it adds the class and creates the corresponding file under the project (not even the solution)
Classes belong to a project, not a solution - you can't compile a solution.
Originally Posted by IliaPreston
Also, if you look at that same dialogue again, it doesn't give me the option to choose an EXISTING class either.
It only lets me add a NEW class.
If you right-click on your project (or any folder in your your project) you can select Add -> Existing Item, and then navigate to the file in question. If you click on the drop down next to the "Add" button then you can add the file as a link rather than copying it to the current project.
Recent versions of Visual Studio also have Shared Projects https://learn.microsoft.com/en-us/pr...s?tabs=windows which might be easier than a folder containing lots of individual source files. Create a shared project containing all of these files, then reference the shared project from your other projects.
Last edited by PlausiblyDamp; Jul 8th, 2024 at 12:25 PM.
-
Jul 8th, 2024, 09:48 PM
#8
Re: Where to put general procedures in C#
Originally Posted by IliaPreston
It doesn't give me any option to save the new class in any location that I wish.
The new item will be added in the location that was selected when you opened the dialogue. If you want to add a new item in a folder, right-click that folder and select the menu option to add a new item. When you click the Add button, the item will be added to that folder. If you have just selected a project then the item will be added to the root folder of that project.
Originally Posted by IliaPreston
After I click "Add", it adds the class and creates the corresponding file under the project (not even the solution)
It would help if you knew how these things work and fit together. Adding a class file to the solution would be possible (I think) but not useful. A class has to be declared in an assembly to be of use and an assembly is generated by building a project. If you want classes that can be used in various projects then create a Class Library project and add the new class to that. That project will then build to a DLL that can be referenced by other EXEs or DLLs. In the same solution, one project can reference another and then they will be built together and can be debugged together. Once your library has been built, other projects can reference it directly or you can create a NuGet package and that can be installed in other projects.
-
Jul 12th, 2024, 08:10 PM
#9
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by dday9
You could simply create the file outside of Visual Studio, open it inside of Visual Studio to edit, and then when you wanted to add it to your project you would use the Add Existing Item option.
Thanks for your help.
I am trying to test what you are saying.
Before even posting my initial post, I had already tried to add a new class (Main menu -> Project -> Add class) which I already explained in post #5.
And this is the class that I had added at that time:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test002SqLite
{
public static class CommonUtilities
{
public static int AddFiveToInt(int Num)
{
Num += 5;
return Num;
}
}
}
Please note that the name of my project (as well as the solution) are both Test002SqLite
And, that same name appears in the above class as the namespace.
The above class is obviously part of the project named Test002SqLite, so, if the namespace in the above class is Test002SqLite, it should be ok (or that is what I guess)
Now, if I were to test the thing that you are saying, I should open Windows Explorer and go to the different folder where I want to create my class, create a new text file and put some code in it similar to the above and save it as for example CommonClass.cs
And then in Visual studio I should add that file to my project.
But, the problem is that I don't think it is right to declare the namespace as Test002SqLite because I need this new class to be part of all my projects in all my solutions.
So, what namespace name should I give it?
Also, if I create the class outside of Visual Studio, and then in Visual Studio I add it to many project (under many solutions) would that be ok?
Please advise.
Thanks.
-
Jul 13th, 2024, 05:20 AM
#10
Re: Where to put general procedures in C#
A namespace is only a logical grouping for your code, it doesn't affect anything other than how you refer to things. If you want to share a class between multiple projects then just give it a namespace that reflects this e.g.
Code:
namespace Common {
}
the only difference is that when referring to this class in one of your projects you would need to either fully qualify the class name with the namespace, or put a using statement at the top of each code file for that namespace.
-
Jul 13th, 2024, 11:45 PM
#11
Re: Where to put general procedures in C#
Originally Posted by IliaPreston
I need this new class to be part of all my projects in all my solutions.
No, you don't. Any class is part of one project in one solution. What you need is for that class to be AVAILABLE TO all your projects in all your solutions. To that end, you should be creating a new solution with a new Class Library project. That project will generate a DLL when built and you can then reference that DLL in any other project that needs to access the types defined in it. How do you think all your projects can access all the types defined as part of .NET? The entire framework is comprised of DLLs that your projects reference as required.
Even better, you can create a NuGet package from the compiled DLL and host it on your development machine. You can then install that package in other projects just like you do first-party and third-party NuGet packages to access the types they contain. NuGet packages are a good way to keep track of library versions and to updated projects with new versions of libraries as they become available.
With regards to namespaces, here's what I recommend. Come up with a "company name" for yourself and prefix everything you do with that. When I was self-employed, my business name was Wunnell Development (my middle name is Philip with one L) and so all my solutions and projects are prefixed with that. Each solution should correspond to a product and then each project should correspond to a component of that product. If I was creating a web site for myself then I might name a solution Wunnell.WebSite and then that might contain projects including Wunnell.WebSite.Model and Wunnell.WebSite.Web. If you're working for a client rather than yourself then you can insert the client name. For instance, I currently work at Spatial Intelligence and we are doing a project for Great Barrier Reef Marine Park Authority called Eye on the Reef. We have a solution named SI.Gbrmpa.Eotr and it contains projects like SI.Gbrmpa.Eotr.Model, SI.Gbrmpa.Eotr.Service, SI.Gbrmpa.Eotr.Service.Interface, SI.Gbrmpa.Eotr.Web and SI.Gbrmpa.Eotr.Web.Test. We also have an internal solution named SI.FileFormats that builds a DLL and creates a NuGet package that we have installed in the Web project of that solution and provides functionality to import and export various data file formats in various of our products.
-
Jul 16th, 2024, 05:43 PM
#12
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by PlausiblyDamp
A namespace is only a logical grouping for your code, it doesn't affect anything other than how you refer to things. If you want to share a class between multiple projects then just give it a namespace that reflects this e.g.
Code:
namespace Common {
}
the only difference is that when referring to this class in one of your projects you would need to either fully qualify the class name with the namespace, or put a using statement at the top of each code file for that namespace.
Thanks for your help.
I am experimenting with your suggestion.
I have created a new solution/project which is .Net Core and added a new class as follows:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Common001Test
{
public static class Comm001Test
{
public static int AddSixToInt(int Num)
{
Num += 6;
return Num;
}
}
}
I have given different names to the class and the namespace as you can see in the above code. (There is a tiny difference).
The file name is Comm001Test.
I don't know why I gave them different names.
Maybe that was not good.
Maybe I should have given them the same name.
But, that is beside the point.
Also, in the same project I have a form. Actually I didn't add that form. It was added to the project when I created the project.
I added a button to the form.
You said:
you would need to either fully qualify the class name with the namespace, or put a using statement at the top of each code file for that namespace
If I fully qualify the method name like this (let's call this Code 1):
Code:
namespace Common001Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnTest001_Click(object sender, EventArgs e)
{
int N = 10;
int Res;
Res = Comm001Test.AddSixToInt(N);
txtDetails.Text = "" + Res;
}
}
}
it works.
That is classname.methodname
But, if I qualify the method name like this (let's call this Code 2):
Code:
private void btnTest001_Click(object sender, EventArgs e)
{
int N = 10;
int Res;
Res = Common001Test.AddSixToInt(N);
txtDetails.Text = "" + Res;
}
it does not work.
That is namespace.methodname
Error CS0234 The type or namespace name 'AddSixToInt' does not exist in the namespace 'Common001Test' (are you missing an assembly reference?) Common001Test D:\Dev\VCS\Tests\Common001Test\Common001Test\Common001Test\Form1.cs 16 Active
I thought this should work.
Why doesn't it work?
Now, instead of qualifying the method name, I try to add a using statement on the top of the code file (let's call this Code 3):
Code:
using Common001Test;
namespace Common001Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnTest001_Click(object sender, EventArgs e)
{
int N = 10;
int Res;
Res = AddSixToInt(N);
txtDetails.Text = "" + Res;
}
}
}
it doesn't work:
Error CS0103 The name 'AddSixToInt' does not exist in the current context Common001Test D:\Dev\VCS\Tests\Common001Test\Common001Test\Common001Test\Form1.cs 17 Active
Also, this one (let's call this Code 4):
Code:
using Comm001Test;
namespace Common001Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnTest001_Click(object sender, EventArgs e)
{
int N = 10;
int Res;
Res = AddSixToInt(N);
txtDetails.Text = "" + Res;
}
}
}
doesn't work:
Error CS0246 The type or namespace name 'Comm001Test' could not be found (are you missing a using directive or an assembly reference?) Common001Test D:\Dev\VCS\Tests\Common001Test\Common001Test\Common001Test\Form1.cs 1 Active
Error CS0103 The name 'AddSixToInt' does not exist in the current context Common001Test D:\Dev\VCS\Tests\Common001Test\Common001Test\Common001Test\Form1.cs 17 Active
Please note that this entire thing is within one same solution/project.
After I fix this bug, I will use that method "AddSixToInt" in other projects, but at this moment I haven't reached that stage. At this moment I am just trying to get it to work within one same project.
Why doesn't code 2 (above) work?
Why doesn't code 3 (above) work?
Why doesn't code 4 (above) work?
Please advise.
Thanks again.
-
Jul 16th, 2024, 08:41 PM
#13
Re: Where to put general procedures in C#
Originally Posted by IliaPreston
Why doesn't code 2 (above) work?
Because that's not legal C# syntax. In C#, any class member has to be qualified by a reference to an instance of that class for instance methods or by the class name for static methods. You seem to be under the impression that it should work like VB, where module members can but don't need to be qualified with the module name. That is not the case. You ALWAYS need to type name to qualify a static method (unless the code is within the type itself, in which case there is an implicit this qualifier). You also seem not to understand what the "fully" in "fully-qualified" means. It means including the full namespace, so fully qualifying that method would mean using Common001Test.Comm001Test.AddSixToInt.
-
Jul 17th, 2024, 07:22 AM
#14
Re: Where to put general procedures in C#
To add to that, you can import (Using) namespace... but not classes.... so. "using Comm001Test;" doesn't work because that's a class... not a namespace. "using Common001Test;" does work because it's a namespace... BUT, as jmc noted, you STILL need to use the class name to for the method. If you think about it, it makes sense... what if you had this:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Common001Test
{
public static class Comm001Test
{
public static int AddSixToInt(int Num)
{
Num += 6;
return Num;
}
}
public static class Comm002Test
{
public static int AddSixToInt(int Num)
{
Num += 6;
return Num;
}
}
}
If you were to simply call "AddSixToInt" ... how would it know which one you wanted? It doesn't. So you need to specify which one you want.
-tg
-
Jul 17th, 2024, 08:28 PM
#15
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by jmcilhinney
Because that's not legal C# syntax. In C#, any class member has to be qualified by a reference to an instance of that class for instance methods or by the class name for static methods. You seem to be under the impression that it should work like VB, where module members can but don't need to be qualified with the module name. That is not the case. You ALWAYS need to type name to qualify a static method (unless the code is within the type itself, in which case there is an implicit this qualifier). You also seem not to understand what the "fully" in "fully-qualified" means. It means including the full namespace, so fully qualifying that method would mean using Common001Test.Comm001Test.AddSixToInt.
Thanks a lot for your help.
You said:
You ALWAYS need to type name to qualify a static method ...
I am not trying to challenge what you are saying, but PlausiblyDamp told me that I can omit qualifying the method name with the class name if I use the using statement in the beginning of the file:
PlausiblyDamp: when referring to this class in one of your projects you would need to either fully qualify the class name with the namespace, or put a using statement at the top of each code file for that namespace
Is what PlausiblyDamp said in the above quote wrong?
I am not trying to blame PlausiblyDamp (in case his statement was wrong).
I am just trying to understand this.
How can you and PlausiblyDamp both be correct?
I am a bit confused.
You are also saying:
You also seem not to understand what the "fully" in "fully-qualified" means. It means including the full namespace, so fully qualifying that method would mean using Common001Test.Comm001Test.AddSixToInt.
If that is the case then why does my Code #1 in Post #12 (copied below) work?
Code:
namespace Common001Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnTest001_Click(object sender, EventArgs e)
{
int N = 10;
int Res;
Res = Comm001Test.AddSixToInt(N);
txtDetails.Text = "" + Res;
}
}
}
The above code works perfectly.
According to your suggestion it shouldn't work.
Please help.
Thanks again
Ilia
-
Jul 17th, 2024, 10:00 PM
#16
Re: Where to put general procedures in C#
Originally Posted by IliaPreston
The above code works perfectly.
According to your suggestion it shouldn't work.
No, I didn't say that it shouldn't work. There's generally no need to fully-qualify anything because you normally import the namespace, either at the file or project level. It's generally more desirable to do that because it makes code more readable. You would generally only full-qualify a name if there was a class of types from two different imported namespaces. The whole point of the full qualification is to disambiguate the name. If there's no ambiguity, there's no need or reason to fully qualify.
I should note that, in this case, you're not actually importing the namespace because you're actually inside the namespace. The form you're writing the code in and the class you're accessing are both in the same namespace, so the compiler doesn't require any further qualification. The current namespace is effectively imported by default.
-
Jul 17th, 2024, 10:14 PM
#17
Re: Where to put general procedures in C#
Originally Posted by IliaPreston
Is what PlausiblyDamp said in the above quote wrong?
We were both a little bit wrong, actually. You have always been able to import a type name in VB with Imports, which is probably why PD thought it was valid here. C# originally only let you import namespaces and not types. I'm not sure which language version introduced the change but you can now import a type in C# with using static rather than just using. I would generally recommend against doing so though. I'd only do that if you're using one particular type a lot in that particular file and it's clear what all the unqualified member references are. If you start doing it willy nilly, you'll make your code harder to read.
-
Aug 1st, 2024, 05:26 AM
#18
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
I did as you told me and everything works perfectly in my test project:
I have a test project that does all kinds of things (the main test project).
Then I have another test project (this one being a common test project) that contains my utility methods
Then in the main test project, I go to the top menu -> Project -> Add Existing Item and browse to the common class in the common project
Then I follow all that you advised, and as a result, I can now call the method (defined in the common project) in the main project.
That is exactly what I wanted to do.
And it works perfectly.
No issues in here.
So, it is time to develop a REAL common project (the above was just a TEST common project), so that I can call its methods in my REAL projects (in the above I called those common methods in the TEST main project).
Now that I have learned how to do it, I need to do it in REAL projects:
So, I create a common project. (It is .Net Core).
The wizard adds a form to it too (which is good anyway)
Before I write my methods (that I need to call in other projects), I think it is a good idea to put a "Hello World" button on the form (just to make sure the project works) before adding the common methods:
https://i.imgur.com/N7sGnny.jpeg
And I double-click on the button (in design mode) expecting C# to show the code for the "Click" event handler.
But, it shows the form code WITHOUT the button's click event handler:
https://i.imgur.com/eXoSGkz.jpeg
I don't know why the click event handler doesn't show.
I go back to the form Design, and while the button is selected, I go to the properties window, and click on the Events button and scroll down to the Click Event (actually it is there even without scrolling) and the correct event name "btnHelloCommon_Click" is already there.
I click on that name and press Enter.
The code window opens again, but still there is no sign of the click event handler:
https://i.imgur.com/eXoSGkz.jpeg
This is unbelieveable.
Why does this happen?
How can I create the click event handler?
Please help.
Thanks.
-
Aug 6th, 2024, 09:15 PM
#19
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Any help on this issue (post #18) will be greatly appreciated.
I just need to know why the event handler is not created.
I close Visual studio.
Then I delete that whole Solution/Project in Windows Explorer.
Then I open Visual Studio again, and create a fresh new solution/project and do the same things.
Again, when I double click on the newly-added button (in design mode), it opens the code page, but does NOT create the event handler for the button:
https://i.imgur.com/eXoSGkz.jpeg
This time, I try to run the project.
It does not run. It gives me an error:
Severity Code Description Project File Line Suppression State
Error CS1061 'CommonForm1' does not contain a definition for 'btnHelloWorld_Click' and no accessible extension method 'btnHelloWorld_Click' accepting a first argument of type 'CommonForm1' could be found (are you missing a using directive or an assembly reference?) CU001 D:\Dev\VCS\Common\CU001\CU001\CommonForm1.Designer.cs 42 Active
Screenshot:
https://i.imgur.com/WOpVIRj.jpeg
Then I click on that error, and it shows me this:
https://i.imgur.com/A4hFof6.jpeg
This problem persists.
Please help.
Thanks.
-
Aug 6th, 2024, 10:02 PM
#20
Re: Where to put general procedures in C#
Can you create event handlers using the Properties window, or does the same thing happen? It seems like VS is broken and it's creating code in one file but not the other. A repair or reinstall is probably required.
-
Aug 8th, 2024, 02:20 AM
#21
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by jmcilhinney
Can you create event handlers using the Properties window, or does the same thing happen? It seems like VS is broken and it's creating code in one file but not the other. A repair or reinstall is probably required.
I do this:
https://i.imgur.com/UOanpIh.jpeg
Then again the same problem (the code window opens, but the event handler is not there):
https://i.imgur.com/uKa850t.jpeg
Then I close Visual Studio, and wait a minute. Then open Visual Studio and open the solution/project in it.
The code window appears:
https://i.imgur.com/69ot9B6.jpeg
But, the Designer does NOT show. Instead, this shows:
https://i.imgur.com/JzbhEj2.jpeg
Back to the code window:
https://i.imgur.com/uKa850t.jpeg
There is no "using" statement at the top of the code.
Why does this happen?
Should I re-install Visual Studio, or is there a simpler way?
One additional note: When I created this solution.project, the form's name was Form1 (assigned by Visual Studio), but, I immediately renamed it to CommonForm1
I did the rename through project explorer (the window above the Properties window)
It asked me "Do you want to rename other places where it is referenced" and I said yes.
Please help.
Thanks
Last edited by IliaPreston; Aug 8th, 2024 at 02:27 AM.
-
Aug 8th, 2024, 06:48 AM
#22
Re: Where to put general procedures in C#
Originally Posted by IliaPreston
Why does this happen?
Sounds like something in VS is corrupt. Exactly what is anyone's guess.
Originally Posted by IliaPreston
Should I re-install Visual Studio, or is there a simpler way?
Try a repair first, which is a specific option in the VS installer. It's basically an in-place reinstall using the same options as the original install, so it should fix any files that have since become corrupted. Hopefully that will work.
-
Aug 22nd, 2024, 12:03 AM
#23
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by PlausiblyDamp
Normally I would right click on the relevant folder in solution explorer, select new, and theat way the item is created in the correct location.
Classes belong to a project, not a solution - you can't compile a solution.
If you right-click on your project (or any folder in your your project) you can select Add -> Existing Item, and then navigate to the file in question. If you click on the drop down next to the "Add" button then you can add the file as a link rather than copying it to the current project.
Recent versions of Visual Studio also have Shared Projects https://learn.microsoft.com/en-us/pr...s?tabs=windows which might be easier than a folder containing lots of individual source files. Create a shared project containing all of these files, then reference the shared project from your other projects.
Thanks for your help.
If you right-click on your project (or any folder in your your project) you can select Add -> Existing Item, and then navigate to the file in question. If you click on the drop down next to the "Add" button then you can add the file as a link rather than copying it to the current project.
I thought it would always be a link, and would NEVER copy the whole class file onto the current project folder.
Let's say if I click on the main "Add" (instead of clicking on the dropdown next to it and then Add as link), does it really COPY the class file onto the current project folder?
If that is the case, then if I later modify the original class, then the COPY that has been copied onto the current project folder will NOT have the latest changes.
That defeat the whole purpose of adding a class to multiple projects.
Also, jmcilhinney says in post #11:
What you need is for that class to be AVAILABLE TO all your projects in all your solutions. To that end, you should be creating a new solution with a new Class Library project. That project will generate a DLL when built and you can then reference that DLL in any other project that needs to access the types defined in it.
What I understand from jmxilhinney's above statement is that there is only ONE copy of the class file, and that the class file does NOT get copied onto each project folder as a separate file.
What you (PlausiblyDamp) are saying in post #7 and what jmcilhinney is saying in post #11 are in contradiction with each other.
I want only ONE copy of the class file being AVAILABLE to multiple solution/projects so that if I later modify that class (for example fix a bug), the new modifications be immediately available to all those projects without copying the new version of the class file onto all those projects' folders (overwriting older versions of the class file)
I am quite confused.
Can you please clarify?
Thanks
-
Aug 22nd, 2024, 12:34 AM
#24
Re: Where to put general procedures in C#
Unless there's some specific reason you need this same class to exist in multiple different places, just create a library, like I already said. Reference that library in the other projects and any types in the library are available. You're trying to complicate something that's very simple.
-
Aug 22nd, 2024, 02:37 AM
#25
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by jmcilhinney
Unless there's some specific reason you need this same class to exist in multiple different places, just create a library, like I already said. Reference that library in the other projects and any types in the library are available. You're trying to complicate something that's very simple.
Well, in the very beginning (that is in post #1) I explained that I need to write some common code that all my solution/projects can use:
I have some C# procedures that are needed in several forms in the project.
So I cannot put them in the code of a specific form.
Where do I put them?
And here is your response (in post #2):
Basically everything in .NET is a class. Forms are classes, just like everything else. Just create one or more classes and put your methods there
And now, with libraries, I google search "what are libraries in c#" and get completely confused.
For example, it gives me this:
https://learn.microsoft.com/en-us/do...andard-library
which is completely confusing
or this:
https://learn.microsoft.com/en-us/do...lass-libraries
which I wonder what language it is.
Honestly, I think these articles are in Japanese language!
Now, here is EXACTLY what I need to do:
I have a number of procedures, for example this one:
Code:
public int RunSqlReturnInt(SQLiteConnection conn, string sql, int AltValForNull = 0, int AltValForNoRec = 0)
{
using (var cmd = new SQLiteCommand(sql, conn))
using (var rdr = cmd.ExecuteReader())
{
if (!rdr.HasRows)
return AltValForNoRec;
else
{
rdr.Read();
var retVal = rdr[0];
if ((retVal == null) || (retVal == DBNull.Value))
return AltValForNull;
return Convert.ToInt32(retVal);
}
}
}
And now MULTIPLE copies of these procedures exist in MULTIPLE places (one copy in each project that uses them)
Having multiple copies of the same code is a nightmare.
What if I find a bug in it and need to fix it?
Then I have to do that fix in all those multiple copies.
This is a real nightmare.
To make things even more confusing, I just noticed something in your response (post #2) that I had somehow missed earlier:
For the record, VB.NET has modules that are implemented to work in basically the same way that modules do in VB6 but they compile to the same things as C# static classes.
Is that only VB.Net or C# as well?
Now, imagine you have the same goal, and want to put this code:
Code:
public static int AddSixToInt(int Num)
{
Num += 6;
return Num;
}
somewhere.
Where would you put it?
Class?
Library?
Module?
Please help.
Thanks.
Last edited by IliaPreston; Aug 22nd, 2024 at 02:40 AM.
-
Aug 22nd, 2024, 03:31 AM
#26
Re: Where to put general procedures in C#
Originally Posted by IliaPreston
Thanks for your help.
I thought it would always be a link, and would NEVER copy the whole class file onto the current project folder.
Creating a link is going to break most forms of version control because having the class outside of the source folder isn't a normal way of doing things.
Originally Posted by IliaPreston
Let's say if I click on the main "Add" (instead of clicking on the dropdown next to it and then Add as link), does it really COPY the class file onto the current project folder?
If that is the case, then if I later modify the original class, then the COPY that has been copied onto the current project folder will NOT have the latest changes.
That defeat the whole purpose of adding a class to multiple projects.
That is exactly what it is doing, how is it defeating the purpose? Should the system assume that adding a file to a project means every time you edit the file every copy should be updated? Adding a link is the workaround for this.
Originally Posted by IliaPreston
Also, jmcilhinney says in post #11:
What I understand from jmxilhinney's above statement is that there is only ONE copy of the class file, and that the class file does NOT get copied onto each project folder as a separate file.
What you (PlausiblyDamp) are saying in post #7 and what jmcilhinney is saying in post #11 are in contradiction with each other.
I want only ONE copy of the class file being AVAILABLE to multiple solution/projects so that if I later modify that class (for example fix a bug), the new modifications be immediately available to all those projects without copying the new version of the class file onto all those projects' folders (overwriting older versions of the class file)
I am quite confused.
Can you please clarify?
Thanks
jmcilhinney isn't saying that at all, he is saying a class is part of one project, not there is only one copy of a class. He also gives the correct solution by suggestion using a class library instead.
-
Aug 22nd, 2024, 03:35 AM
#27
Re: Where to put general procedures in C#
Originally Posted by IliaPreston
Well, in the very beginning (that is in post #1) I explained that I need to write some common code that all my solution/projects can use:
And here is your response (in post #2):
And now, with libraries, I google search "what are libraries in c#" and get completely confused.
For example, it gives me this:
https://learn.microsoft.com/en-us/do...andard-library
which is completely confusing
or this:
https://learn.microsoft.com/en-us/do...lass-libraries
which I wonder what language it is.
Honestly, I think these articles are in Japanese language!
Now, here is EXACTLY what I need to do:
I have a number of procedures, for example this one:
Code:
public int RunSqlReturnInt(SQLiteConnection conn, string sql, int AltValForNull = 0, int AltValForNoRec = 0)
{
using (var cmd = new SQLiteCommand(sql, conn))
using (var rdr = cmd.ExecuteReader())
{
if (!rdr.HasRows)
return AltValForNoRec;
else
{
rdr.Read();
var retVal = rdr[0];
if ((retVal == null) || (retVal == DBNull.Value))
return AltValForNull;
return Convert.ToInt32(retVal);
}
}
}
And now MULTIPLE copies of these procedures exist in MULTIPLE places (one copy in each project that uses them)
Having multiple copies of the same code is a nightmare.
What if I find a bug in it and need to fix it?
Then I have to do that fix in all those multiple copies.
This is a real nightmare.
To make things even more confusing, I just noticed something in your response (post #2) that I had somehow missed earlier:
Is that only VB.Net or C# as well?
Now, imagine you have the same goal, and want to put this code:
Code:
public static int AddSixToInt(int Num)
{
Num += 6;
return Num;
}
somewhere.
Where would you put it?
Class?
Library?
Module?
Please help.
Thanks.
A classlibrary is a type of project, it is how you create a reusable component / shared functionality. If you are using C# shared code would go into a class which would be part of a class library. This classlibrary would then be referenced by the projects that use it's functionality.
Last edited by PlausiblyDamp; Aug 22nd, 2024 at 06:58 AM.
-
Aug 26th, 2024, 07:05 AM
#28
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by PlausiblyDamp
A classlibrary is a type of project, it is how you create a reusable component / shared functionality. If you are using C# shared code would go into a class which would be part of a class library. This classlibrary would then be referenced by the projects that use it's functionality.
Thanks a lot for your help.
Before I go ahead and read on class libraries and how to implement them, let me make sure that that is exactly what I am looking for.
The key point in what I am looking for is that I am looking for a way to write some general-purpose procedures and place them in a file in a common folder (obviously a folder common to all solutions/projects) and NOT in the folder of a specific solution/project, and that the file where I want to put these general-purpose procedures should NEVER be copied onto any solution/project folder.
Instead, that file should be a ONE-OFF file that all solution/projects can access.
For example, I want to put a procedure like this:
Code:
public static int AddSixToInt(int Num)
{
Num += 6;
return Num;
}
in a file that never gets copied anywhere, and if I modify that procedure (AddSixToInt), that change would immediately affect and be seen by all solutions/projects that call that procedure.
So, basically am I right in understanding from your post that a class library is what achieves that goal?
The reason why I am asking for this clarification is that once before (when we were talking about "Add as Link"), I had thought that "Add as Link" was what did that WITHOUT copying, and it turned out I was wrong.
So, the reason I am asking now, is that this time I don't want to misunderstand again.
Please advise.
Thanks again for your help
Ilia
-
Aug 26th, 2024, 07:35 AM
#29
Re: Where to put general procedures in C#
A ClassLibrary project produces a Dll, which is a compiled binary file, this Dll file would be referenced by each project that uses it. This way no source code is copied into each project. This is the most common way of sharing reusable functionality in .Net solutions.
If you don't want to use a compiled dll then you could try the idea of Shared Projects I mentioned back in post #7 https://www.vbforums.com/showthread....=1#post5649477
-
Aug 26th, 2024, 07:46 AM
#30
Re: Where to put general procedures in C#
Originally Posted by IliaPreston
I had thought that "Add as Link" was what did that WITHOUT copying, and it turned out I was wrong.
That IS how that works... how was that wrong?
-tg
-
Aug 29th, 2024, 02:09 AM
#31
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by PlausiblyDamp
A ClassLibrary project produces a Dll, which is a compiled binary file, this Dll file would be referenced by each project that uses it. This way no source code is copied into each project. This is the most common way of sharing reusable functionality in .Net solutions.
If you don't want to use a compiled dll then you could try the idea of Shared Projects I mentioned back in post #7 https://www.vbforums.com/showthread....=1#post5649477
Thanks for your help.
I read that article about Shared Projects, then I did this:
1. I closed Visual Studio.
2. I opened Visual Studio --> Create a new project --> selected "Shared Project" --> clicked "Next"
It created a new Shared Project and showed it in the Visual Studio IDE 3. I go to Main menu --> Project --> Add Class:
4. I change that default name from Project1 to Class1 and click "Add".
The dialogue closes.
Now, I expect to see the Class1 that I have added, but it is nowhere to be found.
I check the Solution Explorer and try to expand everything that I can, but Class1 that I added is nowhere !!!!!!
Then I repeat the exact same steps 3 and 4 above, and add another class.
Again I give this class the name Class1 which is a duplicate name, but when I click "Add", the dialogue closes successfully again, apparently creating the new class with a duplicate name !!!!!!
Again, I look high and low for Class1 and it is nowhere to be found. It can't be found in Solution Explorer, or anywhere else !!!!!!
I need to put this code:
Code:
public static int AddSixToInt(int Num)
{
Num += 6;
return Num;
}
somewhere.
Where do I put it?
Post-script: last week, I uninstalled Visual Studio completely, then rebooted, and then installed it again), so, it is the latest version of Visual Studio.
Please help.
Thanks.
-
Aug 29th, 2024, 02:38 AM
#32
Re: Where to put general procedures in C#
In that dialog you need to select C#, the item above C# Items and select Class. Currently you are trying to create a MSBuild.Directory.Props file and are giving it the name Class1.cs.
-
Sep 1st, 2024, 07:30 AM
#33
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by PlausiblyDamp
In that dialog you need to select C#, the item above C# Items and select Class. Currently you are trying to create a MSBuild.Directory.Props file and are giving it the name Class1.cs.
Thanks a lot for your help.
I did the above, and it worked.
I successfully created a shared project and a class inside it and placed my common procedure it it:
https://i.imgur.com/Ed7VRwp.jpeg
Then I saved and closed Visual Studio.
In Windows Explorer, it looks like this:
https://i.imgur.com/KQqWbFA.jpeg
Then I opened Visual Studio and I opened my HelloWorld Solution/project in it.
Then I tried to add a reference to the above shared project to my HelloWorld project:
https://i.imgur.com/Krnrr6G.jpeg
Then:
I browse to the location where the shared project is located, but it doesn't show the shared project:
https://i.imgur.com/ZZAzGo2.jpeg
I can change the file type dropdown box to "All File Types", and continue that way.
But, should I? (I don't want to just guess and work based on guesswork).
Why doesn't it by default include shared project types as a well?
Please correct me if I am wrong: I think Shared project types should be included in that File Type dropdown list by default.
Should I change the file type dropdown box to "All File Types", and continue that way?
Or have I done the whole thing wrong and I should add the reference in a different way?
Please advise.
Thanks again.
-
Sep 1st, 2024, 08:32 AM
#34
Re: Where to put general procedures in C#
Rather than adding a reference to the project, try adding it as an existing project to the solution. The article linked to back in post #2 even says with shared projects they are in the same solution and there are no references to add.
Last edited by PlausiblyDamp; Sep 1st, 2024 at 11:42 AM.
-
Sep 2nd, 2024, 06:58 AM
#35
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by PlausiblyDamp
Rather than adding a reference to the project, try adding it as an existing project to the solution. The article linked to back in post #2 even says with shared projects they are in the same solution and there are no references to add.
Thanks a lot for your help.
I added the shared project to the main solution:
(This screen print has been taken after the shared project had been already added to the solution, that is why in Solution Explorer it says Solution HelloWorld (2 of 2 projects)):
https://i.imgur.com/BNhCueI.jpeg
Then I call the procedure in that shared project in the main (HelloWorld) project.
But, it gives me this error:
https://i.imgur.com/Kb3hE4x.jpeg
Ok. Maybe I should prefix it with the class name.
I prefix it, and get this error:
https://i.imgur.com/3iTq9Ml.jpeg
Ok. Maybe I should prefix it with the namespace AND class names.
I prefix it, and get this error:
https://i.imgur.com/N58cg8w.jpeg
Ok. Maybe I should prefix it with the namespace but not the class names.
I prefix it that way, and get this error:
https://i.imgur.com/JHIVMtZ.jpeg
Maybe I misspelled the namespace or the class name.
But, no, I didn't. I copied and pasted, so there is no chance of misspelling:
https://i.imgur.com/asq9kKQ.jpeg
I really don't know what it is that I am missing.
Please help.
Thanks.
-
Sep 2nd, 2024, 05:07 PM
#36
Re: Where to put general procedures in C#
In solution explorer, right click your main project, and select Add -> Shared Project Reference.
-
Sep 3rd, 2024, 06:52 AM
#37
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by PlausiblyDamp
In solution explorer, right click your main project, and select Add -> Shared Project Reference.
Thanks a lot for your help.
Before doing what you advised (In solution explorer, right click your main project, and select Add -> Shared Project Reference), I also discovered some other problem and fixed it:
In the class, I changed
Code:
internal class Class1
To
Code:
public static class Class1
After making that change, I tried to run the application, but it didn't run.
Then I did what you advised (In solution explorer, right click your main project, and select Add -> Shared Project Reference).
As a result of that, the application ran successfully.
Thanks a lot for your help.
Just one little problem is that I have to call the procedure with the full prefixes:
Code:
m = TestSharedProject001.Class1.AddSixToInt(n);
Both prefixes are needed. For example, the following:
Code:
m = Class1.AddSixToInt(n);
does not work. I have to have both prefixes for it to work.
Is there a way to get rid of the prefixes?
Please advise.
Thanks.
-
Sep 3rd, 2024, 11:09 AM
#38
Re: Where to put general procedures in C#
Did you try putting a using statement at the top the file, the same way you normally would to remove prefixes?
-
Sep 5th, 2024, 04:19 AM
#39
Thread Starter
Fanatic Member
Re: Where to put general procedures in C#
Originally Posted by PlausiblyDamp
Did you try putting a using statement at the top the file, the same way you normally would to remove prefixes?
After putting a using static statement at the top of the file, I am able to successfully call that procedure without prefixing it.
Thanks a lot for your help.
But, now, I am trying to add another procedure to the shared project and call it similarly in my main project, and I face an even bigger problem.
The new procedure that I want to add is one that deals with sqLite, and that is where the problem occurs.
I already have an existing procedure named "RunSqlReturnInt" in my main project.
I copy it and paste it into the shared project and just rename the new copy to "RunSqlReturnInt_Shared":
Code:
public int RunSqlReturnInt_Shared(SQLiteConnection conn, string sql, int AltValForNull = 0, int AltValForNoRec = 0)
{
using (var cmd = new SQLiteCommand(sql, conn))
using (var rdr = cmd.ExecuteReader())
{
if (!rdr.HasRows)
return AltValForNoRec;
else
{
rdr.Read();
var retVal = rdr[0];
if ((retVal == null) || (retVal == DBNull.Value))
return AltValForNull;
return Convert.ToInt32(retVal);
}
}
}
And I call it in my main project:
Code:
sql = "select count(*) from STUDENTS where STD_NUM = 1001";
Res = Comm001Test.RunSqlReturnInt(conn, sql, -1, -2);
DispStr = DispStr + "Count of one record: " + Res + "\r\n";
sql = "select count(*) from STUDENTS where STD_NUM > 1000";
Res = TestSharedProject001.Class1.RunSqlReturnInt_Shared(conn, sql, -1, -2);
DispStr = DispStr + "Count of more than one record: " + Res + "\r\n";
sql = "select STD_NUM from STUDENTS where STD_NUM = 1001";
Res = RunSqlReturnInt(conn, sql, -1, -2);
DispStr = DispStr + "An integer column value: " + Res + "\r\n";
..........
But, it gives me errors.
Please note that I had already added the sqLite NuGet package to the main project.
But, I did NOT add the sqLite NuGet package to the shared project, because it cannot be added to a shared project:
https://i.imgur.com/uzDMG0R.jpeg
I google searched it and they say the NuGet package cannot be added to a shared project.
So, how do I add an sqLite-related procedure to a shared project?
Please help.
Thanks.
-
Sep 5th, 2024, 05:13 AM
#40
Re: Where to put general procedures in C#
Look at what the error message is saying. It is stating that an object reference is required for a non-static method - there is absolutely nothing there that indicates this is a problem with nuget. Have you tried googling that error? Have you tried seeing if there is any difference between that method and the one that works (especially any differences that might make sense in relation to the error message)?
You don't compile a Shared Project, it is compiled into the project that uses it, that is why you cannot add nuget packages to the shared project - they are added to the project that is using your shared code.
The error messages exist for a reason, just because you are using a shared project doesn't mean any and all errors are automatically due to the existence of the shared project.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|