Can't import classes from same namespace - c#

I'm fairly new to .NET and I'm trying to get an old program to work that no longer has it's .csproj file. I've managed to receive an old .sln file from the creator and opened the solution in VS.
From what I can see this is a Developer Web Server project?
Here is the issue.
In the folder Smreka there are 2 files, log.cs and smreka.cs. The log.cs contains the implementation of a class Logger, which I am trying to import in to smreka.cs. They are both using the same namespace Bum.Iglavci.Smreka so as far as I know, I should be able to import the Logger class without any issues.
The problem is that the compiler just can't see it. If I try to directly import it with using static Bum.Iglavci.Smreka.Logger;, I get an error Feature 'using static' is not available in C# 5. Please use language version 6 or greater.
I would like to know why the namespace can't see each other. Is it because I'm missing the .csproj file? Does Developer Web Server even need a .csproj file? If so what's the best way to generate one?
EDIT:
Due to some confusion I'll try to add more details regarding how log.cs and smreka.cs look like. The files are actually a lot longer but I think this should give an idea.
log.cs:
namespace Bum.Iglavci.Smreka{
public class Logger{
public Logger(){
}
public void DoSomething(){}
}
}
smreka.cs:
namespace Bum.Iglavci.Smreka{
public class Baza{
private Logger log;
public Baza(){
log = new Logger();
}
}
}
The compiler has no idea what Logger is under property private Logger log; It states the error The type or namespace name 'Logger' could not be found (are you missing a using directive or an assembly reference?)
I think the namespace is correctly placed, that's why i have a feeling there's something wrong with the project or the solution itself that i need to fix.

Since both classes are in the same namespace they are already able to use each other. You can acces the class by simply doing the following. Let's take Log as the class to call the other class.
Log class:
namespace Bum.Iglavci
{
public class Log
{
public static void ExecuteDoSomething()
{
Smreka.DoSomething();
}
}
}
Smerka class:
namespace Bum.Iglavci
{
public class Smerka
{
public static void DoSomething()
{
//execute code here
}
}
}

It could be possible that the files have the Buil Action property set to
None this will not compile the files. Set it to C# Compiler, this should solve it.
If you don't know how to acces the properties of a file.
Right click the file
Navigate to Properties in the bottom of the list
Set the Build Action to C# compiler (see image)

I found no simple solution. I now created a new .net framework application project and added the files in to the new project. For some reason the namespace works correctly now and the files can see each other in the same namespace.

Yes the error comes from the fact that you don't have a .csproj file.
Such files contain the list of files to compile when building a project. Just having the solution file is not enough.
I suggest some readings on project and solution using Visual Studio :
https://learn.microsoft.com/en-us/visualstudio/ide/solutions-and-projects-in-visual-studio?view=vs-2022
https://learn.microsoft.com/en-us/visualstudio/get-started/tutorial-projects-solutions?view=vs-2022

Related

Access source generated class property/method in main code MSVS 2022

I created my first source generator (ISourceGenerator) with public property and public method.
Let this class be like this:
public partial class MyClass1 // Manually written code
{
}
public partial class MyClass1 //Source Generated code
{
public string GeneratedProperty { get; set; }
public string GeneratedMethod() => "lala";
}
Both of these classes are located in the same namespace (for example, MyNamespace - it doesn't matter really).
So, I'm trying this:
var myClass = new MyClass1(); // Correct
Console.WriteLine(myClass.GeneratedMethod()); //Wrong, "MyClass1 doesn't contain definition for GeneratedMethod..."
When I say MSVS generate sources as files in the concrete directory, I have the code above working well.
So, I want to have an ability to use generated code "on fly" when I write code without generation source files each time manually. Also earlier manually generated source files are not deleted when I'm generating new source files.
Is it possible?
Thank you.
UPD. I have this message from Visual Studio:
"Warning CS8032 An instance of analyzer Generators.Factory.AbstractFactoryGenerator cannot be created from ...\bin\Debug\netstandard2.0\SourceGeneratorsLibrary.dll: Exception has been thrown by the target of an invocation."
Maybe this significant?
UPD2. https://pastebin.com/qtvrugu3 - this is my Source Generator code. Pls, don't blame me, It's just my first steps.
As far as I know, programming is case sensitive, well at least C# so myClass() is different from MyClass(). also hence you are using the string data type, try casting it as string via
Convert.ToString(MyClass1().GeneratedMethod());
or
MyClass1().GeneratedMethod().ToString();
hope this answers you question.
It seems you have developed your analyzer but not actually referenced it from a project?
To use your analyzer you simply add it as as project reference, but make sure it's marked up as an analyzer in the .csproj file:
<ItemGroup>
<ProjectReference Include="MyGenerator\MyGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
Or something like that, adjusted to your solution.

Specifying cs file to build with dotnet CLI

Suppose I have two files in my current working directory:
// file1.cs
Console.WriteLine("file1");
//file 2.cs
Console.WriteLine("file2");
In powershell, I do a dotnet new and delete the automatically generated Program.cs file. Then I do a dotnet build and get an error:
Only one compilation unit can have top level statements
I understand why this occurs, but I would like to be able to have full control of which .cs file is being targetted, while the other ones get ignored.
Is there any way to achieve this without having to create a whole new project for every file?
Doing this with .NET doesn't seem to be possible as of now. An issue on the dotnet/sdk GitHub has requested for this feature to be implemented.
However, you can use the C Sharp Compiler to compile a Windows executable and specify a .cs file with csc file1.cs
file1.cs:
using System;
Console.WriteLine("File 1");
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/top-level-statements
These files both use top-level statements. It implies that they both contain the Main method where program execution starts. You can only have one entry point. Generally, C# code is going to be contained within classes. Define a class in one (or both) files and put your methods within.
// Program.cs
public class Program
{
static void Main()
{
Console.WriteLine("Program.cs");
}
}
// Util.cs
public class Util
{
public static void Display()
{
Console.WriteLine("Util.cs");
}
}

How to use "UnityEngine" in runtime-compiled C# code?

I am trying to compile code at runtime using C#, Unity and this tutorial. I've got everything running, but want to be able to use UnityEngine methods like Debug.Log(); in the pseudo-code. In order to do so, I wrote using UnityEngine; in it, but got the following error:
The type or namespace name "UnityEngine" could not be found. Are you missing an assembly reference?
How do I solve this?
I have tried adding a reference of UnityEngine to CompilerParameters.ReferencedAssemblies like this:
//parameters is of type CompilerParameters
parameters.ReferencedAssemblies.Add("UnityEngine.dll");
but that gives me the following error:
Metadata file UnityEngine.dll could not be found.
This is the most relevant part of my code, but you won't be able to reproduce it like that. Instead, get the code from the above mentioned tutorial.
public void Compile()
{
string code = #"
using UnityEngine;
namespace First
{
public class Program
{
public static void Main()
{
" + "Debug.Log(\"Test!\");" + #"
}
}
}
";
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add("UnityEngine.dll");
}
Since I am inexperienced with C#, and only use it with Unity, I don't know what a .dll file is and am clueless about where to start when fixing this. I am thankful for any kind of help!
You are supposed to put the path of the UnityEngine.dll there, not just UnityEngine.dll, unless it exists in the working directory, which is highly unlikely.
According to this answer, you can easily find UnityEngine.dll (and other dlls as well) in your file system. It is under Editor\Data\Managed, so you should write:
parameters.ReferencedAssemblies.Add(#"C:\\path\to\your\unity\installation\Editor\Data\Managed\UnityEngine.dll");
I tried some of the open source solutions, but couldn't find a solution which worked on all 3 platforms. Finally I bought this asset, which works without problems on Windows, Mac and Linux: https://assetstore.unity.com/packages/tools/integration/dynamic-c-82084 The documentation and support is very good. For example I had a problem that I couldn't compile a class which uses the Unity Screen class, and the support told me that I had to include the UnityEngine.CoreModule.dll in the settings page of the asset, which solved the problem.
PS: I don't get money for this recommendation, I'm just a happy user of the asset.

In Visual Studio C# project do files aware the other file content without putting a using statement?

Say If we use two separate files called a.cs and b.cs in a C# project using VISUAL STUDIO, my question is does one file aware of the other WITHOUT putting a using statement about the other file. ie In the file a.cs can we use a class that is already defined in b.cs but not putting a using b.cs; statement in the beginning of the file?.When we compile altogether will the project know each file content and won't raise any error?
I guess you are on the wrong track here. Files don't interact with each other. But the classes do. Namespaces are used to refer to the class that are meant to be used. You can change the file name to anything several times, it won't affect your project. Moreover you can put many classes inside the same file name under the same namespace and you won't have to use using.
Just consider this scenario, Namespace are the area code, and the phone numbers are the classes. Being in the same area already, you don't have to use the area code to call a different number that exists in the same area. But if you are dialling a number outside your area, you would want to use the area code. Basically by adding area code(namespace) infront of the number, you are applying using to refer to the other number(class). Hope you got the idea.
Edit: Explaining programmatically
Suppose this is your Area
using something;
using someotherthing;
namespace MyMainNamespace
{
private class MyMainClass
{
private void blahblah { ... }
}
private class ClassABC
{
private void blahblah { ... }
}
private class ClassXYZ
{
private void blahblah { ... }
}
}
See, in the above example, to interact with the MyMainClass, ClassABC & ClassXYZ. you don't have to use using MyMainNamespace;. Because they all lie in the same area MyMainNamespace. But there exists a class in another namespace like shown below:
using something;
using someotherthing;
namespace SubNamespace
{
public class SecondaryClass
{
public void apple{ ... }
}
}
If you want to access SecondaryClass which lies in SubNamespace(different area) you would have to use using SubNamespace; in your main area. Like:
using something;
using someotherthing;
using SubNamespace; //add the namespace
namespace MyMainNamespace
{
private class MyMainClass
{
private void blahblah {
...
// Now you can use methods & functions that exist in `SecondaryClass`
SecondaryClass secondary = new SecondaryClass();
secondary.apple();
....
....
}
}
}
Hope this is enough to get the idea by now
Also, it doesn't matter that these namespace(MyMainNamespace & SubNamespace) lies in the same file or different file. You NEVER REFER TO THE FILENAME(filename.cs) by applying using. You ALWAYS REFER TO THE NAMESPACES.
If the C# code in a.cs and b.cs are inside the same namespace, then no using statement should be needed. If the 2 cs files use different namespaces, then you will have to put a using statement for the namespace of the code you want to reference.

I'm getting the "missing a using directive or assembly reference" and no clue what's going wrong

I'm trying to allow a user to enter data into a textbox that will be added to the web.config file. I've added the relevent lines to the web.config file but when I make this class all goes wrong.
I keep getting the are you missing a using directive or assembly refenrence error whenever I try to run my app. I have looked at the other times this question has been asked and can't seem to figure out where I'm going wrong. The thing is that I am extremely new to Visual Studio and am just left blank at what could be the answer.
Below here is the class file that's generating the error. I hope I've included everything you need to assist me. Thank you.
using System.Collections.Generic;
using System.Linq;
using System.Configuration;
namespace WebConfigDemo
{
public class CompanyConfigSection : ConfigurationSection
{
[ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
public CompanyConfigCollection Companies
{
get
{
return (CompanyConfigCollection)this[""];
}
set
{
this[""] = value;
}
}
}
public class CompanyConfigElement : ConfigurationElement
{
[ConfigurationProperty("id", IsKey = true, IsRequired = true)]
public int Id
{
get
{
return (int)this["id"];
}
set
{
this["id"] = value;
}
}
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return this["name"].ToString();
}
set
{
this["name"] = value;
}
}
} '
public class CompanyConfigCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new CompanyConfigElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((CompanyConfigElement)element).Id;
}
}
public class CompaniesConfig
{
private static readonly Dictionary<int, CompanyConfigElement>
Elements;
static CompaniesConfig()
{
Elements = new Dictionary<int, CompanyConfigElement>();
var section = (CompanyConfigSection)ConfigurationManager.GetSection ("companies");
foreach (CompanyConfigElement system in section.Companies)
Elements.Add(system.Id, system);
}
public static CompanyConfigElement GetCompany(int companyId)
{
return Elements[companyId];
}
public static List<CompanyConfigElement> Companies
{
get
{
return Elements.Values.ToList();
}
}
}
} '
Any help is appreciated
You probably don't have the System.Configuration dll added to the project references. It is not there by default, and you have to add it manually.
Right-click on the References and search for System.Configuration in the .net assemblies.
Check to see if it is in your references...
Right-click and select Add Reference...
Find System.Configuration in the list of .Net Assemblies, select it, and click Ok...
The assembly should now appear in your references...
.Net framework of the referencing dll should be same as the .Net framework version of the Project in which dll is referred
If you've tried the above solutions and haven't found the answer, make sure that the .NET versions of all projects are the same.
I ran into this problem when importing a .NET version 4.6.1 into a .NET version 4.6.2 project. Without any warnings from Visual Basic!
More Info: The type or namespace name could not be found
Your using statements appear to be correct.
Are you, perhaps, missing the assembly reference to System.configuration.dll?
Right click the "References" folder in your project and click on "Add Reference..."
This problem would be caused by your application missing a reference to an external dll that you are trying to use code from. Usually Visual Studio should give you an idea about which objects that it doesn't know what to do with so that should be a step in the right direction.
You need to look in the solution explorer and right click on project references and then go to add -> and look up the one you need. It's most likely the System.Configuration assembly as most people have pointed out here while should be under the Framework option in the references window. That should resolve your issue.
I have observed a quote ' in your 1st line and also at the end of your last line.
'using System.Collections.Generic;
Is this present in your original code or some formatting mistake?
I had the same problem earlier today. I could not figure out why the class file I was trying to reference was not being seen by the compiler. I had recently changed the namespace of the class file in question to a different but already existing namespace. (I also had using references to the class's new and previous namespaces where I was trying to instantiate it)
Where the compiler was telling me I was missing a reference when trying to instantiate the class, I right clicked and hit "generate class stub". Once Visual Studio generated a class stub for me, I coped and pasted the code from the old class file into this stub, saved the stub and when I tried to compile again it worked! No issues.
Might be a solution specific to my build, but its worth a try.
In some cases, when necessary using has been obviously added and studio can't see this namespace, studio restart can save the day.
I was getting warnings about different versions in .NET framework; I ignored them.
The project compiles fine making the change in the solution's properties.
I'm using Visual Studio Code and could not use instructions from above so I found another way to fix the problem with referencing to namespace from another file.
All what need to be done is to add include to your .csproj file e.g:
<ItemGroup>
<Compile Include="filename.cs" />
</ItemGroup>
Then you can use namespaces from filename.cs
The following technique worked for me:
1) Right click on the project Solution -> Click on Clean solution
2) Right click on the project Solution -> Click on Rebuild solution

Categories