dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.04k stars 4.03k forks source link

error CS0518: Predefined type 'System.Object' is not defined or imported #12393

Closed Imisnew2 closed 2 years ago

Imisnew2 commented 8 years ago

Version Used: Both:

OS:

Steps to Reproduce:

  1. Clone roslyn repo. Checkout one of the above versions. Run "make".
  2. Attempt to compile a trivial C# source file, e.g. one generated by "dotnet new": "Binaries/Debug/csccore/csc Program.cs"

Expected Behavior: The program compiles.

Actual Behavior: Error CS0518 is generated.

I figured out that mscorlib.dll in that directory only has forwarded types. I compiled coreclr and found the same thing there too... Referencing "System.Private.Corelib.dll" solves the issue (used ILSpy to figure out that's the assembly mscorlib.dll was referencing and just guessed). Referencing mscorlib.dll does NOT solve the issue (as one might expect).

My use-case for this workflow is to be able to package a C# compiler so that it's self-contained (does not rely on the system or any setup / downloading / caching). Is there another preferred way to do this instead?

gafter commented 8 years ago

@agocke @jaredpar Can you please help answer this?

agocke commented 8 years ago

This is a bit tricky. Fundamentally, the compiler is not concerned with providing supporting assemblies like mscorlib/System.Runtime -- that's the job of the framework. CoreFX has decided to build an implementation for the framework where they split the compile surface area and the runtime surface area across different DLLs. This is why NuGet packages contain separate ref and lib folders.

All of this is to say: you're in a bit of a bind. CoreFX will expect that you compile against their ref assemblies (as provided by NuGet) and run against their implementation assemblies (as provided by NuGet). There's no simple single mscorlib that you can both compile and run against and expect to interop safely with other code.

agocke commented 8 years ago

Also, I should say that the C# compiler understands none of this: it just consumes reference assemblies and emits code. NuGet+project.json/msbuild coordinate behind the scenes to pick a specific set of reference assemblies to pass to the compiler and then coordinate to deploy the appropriate set of implementation DLLs for those references, along with the output from the compiler. The CoreCLR runtime handles the rest.

jaredthirsk commented 8 years ago

"All of this is to say: you're in a bit of a bind"

Is there any sort of plan to get this working?

I am trying to do scripting in .NET Core using Roslyn 1.3.2, and it works until I try to communicate with the script via my own classes in Global variable. (It is looking for System.Object in the System.Runtime.dll but can't find it, even if I reference it.)

agocke commented 8 years ago

At the moment, we have no plan to make it easy to use csc.exe in this manner. The guidance is to use the dotnet CLI tooling for the time being. Even if some modification where to be made here, it would be on the framework to provide unified and/or simplified reference assemblies for the compiler. The compiler will never have more complicated type or assembly resolution than it does now (by design).

Imisnew2 commented 8 years ago

@agocke I see. My concern is it is non-intuitive to ask the user to explicitly reference System.Runtime.dll / System.Private.Mscorlib.dll; Mscorlib contains a bunch of TypeForward declarations to other assemblies, so it has the information of where they might be.

The "ref" assemblies you speak from NuGet+project.json/msbuild of contain actual definitions but no implementations; compare this to mscorlib which only contains TypeForward declarations. "~/.nuget/packages/Microsoft.NETCore.Portable.Compatibility/1.0.1/ref/netstandard1.0/mscorlib.dll" still only has TypeForward declarations. Should CSC (or whatever assembly reading library roslyn is using) not resolve TypeForward declarations? I could argue: what is the point of TypeForward declarations in mscorlib if there's not a "ref" mscorlib? Every tool/developer/whatever would have to manually probe mscorlib.dll, figure out which assemblies it references, and reference those directly should they want to use those types. At that point, does the IL generated say the type came from "System.Runtime.dll" or "mscorlib.dll"?

That said, if using an old mscorlib (say, from .NET Framework 4.X), presumably the above "csc Program.cs" scenario would work... although that requires understanding the default logic for finding mscorlib.dll (so that one could setup an environment where the default mscorlib found is the one you want) or always requiring"-nostdlib -reference:othermscorlib.dll".

agocke commented 8 years ago

@Imisnew2 Right, here's the problem:

My concern is it is non-intuitive to ask the user to explicitly reference System.Runtime.dll / System.Private.Mscorlib.dll

The design is that the user should never explicitly reference anything. csc is not meant to be used directly, its meant to be plugged into by a coordination or build system, like project.json + dotnet build/MSBuild.

And yes, you're correct that this is different from .NET desktop, where csc Program.cs is a valid and reasonably simple thing for a user to do. With the current CoreFX factoring and forwarding, this is just not a human-understandable amount of complexity.

tmat commented 8 years ago

@jaredthirsk Could you share more details on how you do scripting? This issue problem seems unrelated to scripting.

jaredthirsk commented 8 years ago

I'm having trouble getting Roslyn to find System.Object for my class.

I was trying http://www.strathweb.com/2016/03/roslyn-scripting-on-coreclr-net-cli-and-dnx-and-in-memory-assemblies/ so I could use my application's types in the scripting code:

The scripting APIs generally work just fine when you try to use them against .NET Core targets.

The problem arises when you are trying to pass in a reference to the current application assembly to your script. This can be needed for a number of reasons – for example you may want to use the results of the scripting operations in your main program or simply use the types from your main program inside the scripting code.

Here are some relevant snippets. Let me know if you want help debugging the full package to try yourself:
(It's on github at https://github.com/jaredthirsk/Core with LionFire.Execution.Program as the startup project)

public ScriptOptions Options {
    get {

        var options = ScriptOptions.Default
            .AddImports("System")
            .AddReferences("System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") // Doesn't work!?
            .AddReferences("System.Runtime") // Doesn't work!?
            .AddReferences("System.Private.Mscorlib") // Doesn't work!?
    #if NET461
                .AddReferences(typeof(System.Security.Cryptography.Aes).GetTypeInfo().Assembly) // Doesn't work!?
                    .AddReferences("System.Security.Cryptography.Algorithms") // Doesn't work!?
    #endif
                    .AddReferencesCore(typeof(MyGlobals).GetTypeInfo().Assembly)
            .AddReferencesCore(typeof(object).GetTypeInfo().Assembly) // Doesn't work!?
            .WithSourceResolver(new SourceFileResolver(ImmutableArray<string>.Empty, ScriptsDirectory))
            ;
        return options;
    }
}

public static unsafe ScriptOptions AddReferencesCore(this ScriptOptions options, Assembly assembly)
{
    // See http://www.strathweb.com/2016/03/roslyn-scripting-on-coreclr-net-cli-and-dnx-and-in-memory-assemblies/
#if NET461
            options.AddReferences(assembly);
#else
    byte* b;
    int length;
    if (assembly.TryGetRawMetadata(out b, out length))
    {
        var moduleMetadata = ModuleMetadata.CreateFromMetadata((IntPtr)b, length);
        var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata);
        var result = assemblyMetadata.GetReference();
        options.AddReferences(result);
    }
    else
    {
        throw new Exception("Failed to get raw metadata for assembly: " + assembly.FullName);
    }
#endif
    return options;
}

Microsoft.CodeAnalysis.Scripting.Hosting.InteractiveAssemblyLoader loader = new Microsoft.CodeAnalysis.Scripting.Hosting.InteractiveAssemblyLoader();

public Task<bool> Initialize()
{
    //CSharpScriptEngine.Execute( // new Roslyn 2.x API?
    script = Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.Create(myCSharpCodeString
    , Options
#if GLOBALS
        , typeof(MyGlobals)
#endif
        , loader
    );

    return Task.FromResult(script != null);
}

public Task Start()
{
    cts = new System.Threading.CancellationTokenSource();
#if GLOBALS
    var roslynRunTask = script.RunAsync(new MyGlobals(), cts.Token); // Object type not found, please add reference to System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
#else
        var roslynRunTask = script.RunAsync(cancellationToken:cts.Token);
#endif
    // ...
}

public class MyGlobals
{
    public string A = "123";
    public int B = 456;
}

Script contains some irrelevant stuff then this: return A + " got global!";

Exception: AggregateException with InnerException of

{Microsoft.CodeAnalysis.Scripting.CompilationErrorException: (1,7): error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
   at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter)
   at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, CancellationToken cancellationToken)
   at LionFire.Execution.Roslyn.Scripting.RoslynScriptExecutionController.Start()
   at LionFire.Execution.ExecutionContextExtensions.<Start>d__1.MoveNext()}
Imisnew2 commented 8 years ago

Thanks @agocke. I guess you can close issue this as user-error, the solution being: figure out what to reference and reference it. Although, documentation surrounding how to invoke csc after building the repo would be nice, though.

For example... previous csc, as a minimum, only needed mscorlib (Microsoft Core Library?), and even then, it /really/ only needed certain types to be defined therein. Could the required types be documented, and, or at the very least, document which assemblies (that would contain the required types) should always be referenced if using the .NETCore framework?

Thanks for the replies, all.

jaredthirsk commented 8 years ago

Anyone have any idea how I can get the CompilationErrorException "The type 'Object' is defined in an assembly that is not referenced." to go away?

jaredpar commented 8 years ago

@jaredthirsk in general this error occurs because the compiler is not given a reference to mscorlib or System.Runtime (which depends on the type of project being compiled). Can you give us a bit more information about what the project structure is?

jaredthirsk commented 8 years ago

@jaredpar The project is .NET Core, using Roslyn 1.3.2. What else do you need to know? Has anyone been able to get scripting working in .NET Core using Roslyn 1.3.2? If so, what references do they use? I understand .NET Core has a different system of reference assemblies and implementation assemblies and I'm not sure how to feed both to Roslyn.

My full project is up at:

(It's on github at https://github.com/jaredthirsk/Core with LionFire.Execution.Program as the startup project)

tmat commented 8 years ago

@jaredthirsk I have tried run the project but I see this error:

TEMP - Failed to load class LionFire.Environment.CommandLine.LionEnvironmentCliHandlers, LionFire.Environment.CommandLine, Version=0.1.0.0
test: LionFire.CommandLine.CommandLineArgs, LionFire.CommandLine, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null
Exception loading assembly: E:\src\Trading\src\LionFire.Trading.Feeds.TrueFx\bin\Debug\netstandard1.6\TestLx.cs.dll
System.IO.DirectoryNotFoundException: The system cannot find the path specified. (Exception from HRESULT: 0x80070003)
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
   at LionFire.Execution.Initialization.LocalAssemblyFromUriResolver.<>c__DisplayClass3_0.<ResolveAssemblyFromName>b__0() in D:\Temp\JT\src\LionFire.Execution\Execution\Initialization\Assembly\LocalAssemblyFromUriResolver.cs:line 77

Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.AggregateException: One or more errors occurred. (nuget support coming soon) ---> System.NotImplementedException: nuget support coming soon
   at LionFire.Execution.Initialization.AssemblyFromNugetResolver.Resolve(ExecutionConfig config)
   at LionFire.Execution.Initialization.ExecutionConfigResolver.<ResolveSourceContent>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at LionFire.Execution.Initialization.ExecutionInitializer.<Initialize>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at LionFire.Execution.ExecutionContextExtensions.<Initialize>d__0.MoveNext()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at LionFire.Execution.Hosting.ExecutionHostConsoleApp.Start(String[] args)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at LionFire.CommandLine.Dispatching.CliDispatcher.RunHandler(MethodInfo handler, Object instance, Object context, String[] args, CommandLineArgs cla)
   at LionFire.CommandLine.Dispatching.CliDispatcher.Dispatch(String[] args, Object handlerInstance, Type handlerClass, Object context, CliDispatcherOptions options)
   at LionFire.Applications.CommandLine.ConsoleApp.Run(String[] args)
   at LionFire.Execution.Hosting.Program.Main(String[] args)

Could you please create a simple project that directly demonstrates the loading issue?

GeirGrusom commented 8 years ago

I have a similar issue. No matter what I try I get the error message that System.Object cannot be found and I need to import System.Runtime.

git@github.com:GeirGrusom/RoslynScript.git

jaredthirsk commented 8 years ago

@tmat @jaredpar Sorry I have been busy with other things, but GeirGrusom provided a simple example above of the failed resolution of System.Object in .NET Core.

epsitec commented 7 years ago

I had the same kind of issue with decimal not being defined (missing reference to System.Runtime, Version=4.0.20.0). I've written a blog post with a workaround.

tmat commented 7 years ago

@epsitec Have you tried the latest version 2.0.0-rc3?

epsitec commented 7 years ago

@tmat I can confirm that even when using 2.0.0-rc3 I still see this if I only specify ScriptOptions.Default:

{"(1,1): error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'."}

tmat commented 7 years ago

Can you share your project?

epsitec commented 7 years ago

I'll extract the code into a stand-alone solution in order to share the sample, yes.

epsitec commented 7 years ago

@tmat it took me longer than I expected to be able to reproduce the issue outside of our product. The crash is related to the type used for the globals. I had to set up three projects:

Calling the script compiler with instances of Mine or Locals works fine. Calling it with an instance of Globals produces this exception:

The type 'Decimal' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

Here is the sample project: https://github.com/epsitec/rnd-csharpscript-netstandard

tmat commented 7 years ago

Thanks, I'll take a look.

waynebrantley commented 7 years ago

@epsitec Concerning your blog post. I was able to take what you wrote and get your sample working. However, as soon as I use a DateTime time, I am back to the same error. Any ideas?

The type 'DateTime' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
public static string GetAssemblyLoadPath(this System.Type type)
{
    return ServiceLocator.AssemblyLoader.GetAssemblyLoadPath (type.GetTypeInfo ().Assembly);
}

Not sure what service locator is, so assume you just meant:

public static string GetAssemblyLoadPath(this System.Type type)
{
    return type.Assembly.Location;
}

Additionally, not that it matters, but your example code var script = CSharpScript.Create<int> ("42m", options: options, globalsType: typeof (Globals)); should be var script = CSharpScript.Create<decimal> ("42m", options: options, globalsType: typeof (Globals));

@tmat Hope you are finding the answer. If you install a package that uses .NET Standard and csharpscript, it is broken.

waynebrantley commented 7 years ago

Well, what I said was not exactly true. It does work for DateTime. What I am running into is I have a simple extension defined in a class library in a nuget package like this:

public static DateTime GetFirstDateOfMonth(this DateTime date)
{
    return new DateTime(date.Year, date.Month, 1);
}

That class library takes a dependency on .net standard 1.4.

If I try to run a script that uses that extension it fails with the DateTime type issue. If I define that same extension, it works just fine. So referencing any code in a library that depends on .net standard is broken.

All these are fine, except the last which says I need a reference to ``System.Runtime, Version=4.0.20.0"

var script1 = CSharpScript.EvaluateAsync<DateTime>("System.DateTime.Parse(\"12/15/2012\")", DefaultOptions);
var script2 = CSharpScript.EvaluateAsync<DateTime>("System.DateTime.Today", DefaultOptions);
var script3 = CSharpScript.EvaluateAsync<DateTime>("new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1)", DefaultOptions);
var script4 = CSharpScript.EvaluateAsync<DateTime>("System.DateTime.Today.GetFirstDateOfMonthLocallyDefined()", DefaultOptions);
var script5 = CSharpScript.EvaluateAsync<DateTime>("System.DateTime.Today.GetFirstDateOfMonth()", DefaultOptions);
epsitec commented 7 years ago

@waynebrantley the initial analysis in my blog post was based on the wrong assumptions. I really need to include multiple .NET Standard projects for the error to show up, as I have demonstrated in the sample solution found at https://github.com/epsitec/rnd-csharpscript-netstandard (and as you found out, this has something to do with referencing code in .NET Standard libraries).

By the way, you are right, ServiceLocator.AssemblyLoader calls into code which comes from our framework and allows us to reach into Assembly.Location, even on .NET Standard 1.x where Location is not available.

Pilchie commented 7 years ago

@jinujoseph can you re-triage? This was in the 2.0 milestone.

tmat commented 7 years ago

I think there is a lot of confusion around referencing .NET Core libraries. Runtime code generation using Roslyn compilations in .NET Core App clarifies.

It would definitely be desirable to make it simpler to avoid above issues.

kinglionsz commented 3 years ago

pls references πŸ’― πŸ‘πŸ‘ https://github.com/dotnet/sdk/issues/8742#issuecomment-744126710

kinglionsz commented 3 years ago

This is the scripts:

`

#!/bin/bash

#dotnethome=`dirname "$0"`
dotnethome=`dirname \`which dotnet\``
sdkver=$(dotnet --version)
fwkver=$(dotnet --list-runtimes | grep Microsoft.NETCore.App | awk '{printf("%s", $2)}')
dotnetlib=$dotnethome/shared/Microsoft.NETCore.App/$fwkver

if [ "$#" -lt 1 ]; then
    dotnet $dotnethome/sdk/$sdkver/Roslyn/bincore/csc.dll -help
    echo dotnethome=$dotnethome
    echo sdkver=$sdkver
    echo fwkver=$fwkver
    echo dotnetlib=$dotnetlib
    exit 1
fi

progfile=$1
prog="${progfile%.*}"
echo -r:$dotnetlib/netstandard.dll > /tmp/$prog.rsp
echo -r:$dotnetlib/System.dll >> /tmp/$prog.rsp
echo -r:$dotnetlib/Microsoft.CSharp.dll >> /tmp/$prog.rsp
for f in  $dotnetlib/System.*.dll; do
    echo -r:$f >> /tmp/$prog.rsp
done

dotnet $dotnethome/sdk/$sdkver/Roslyn/bincore/csc.dll -out:$prog.dll -nologo @/tmp/$prog.rsp $* 
if [ $? -eq 0 ]; then
#  if test -f "$prog.exe"; then
   if test -f "$prog.dll"; then
    if ! test -f "$prog.runtime.config"; then
        echo "{
  \"runtimeOptions\": {
    \"framework\": {
      \"name\": \"Microsoft.NETCore.App\",
      \"version\": \"$fwkver\"
    }
  }
}"  > "$prog.runtimeconfig.json"
    fi
  fi
fi
echo /tmp/$prog.rsp: 
cat /tmp/$prog.rsp
rm /tmp/$prog.rsp

`

NET Core SDK (reflecting any global.json): Version: 3.1.100 Commit: cd82f021f4

Runtime Environment: OS Name: ubuntu OS Version: 20.04 OS Platform: Linux RID: linux-x64 Base Path: /root/dotnet/sdk/3.1.100/

Host (useful for support): Version: 3.1.0 Commit: 65f04fb6db

.NET Core SDKs installed: 3.1.100 [/root/dotnet/sdk]

.NET Core runtimes installed: Microsoft.AspNetCore.App 3.1.0 [/root/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.0 [/root/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs: https://aka.ms/dotnet-download

jaredpar commented 3 years ago

@kinglionsz can you explain what problem you are hitting here?

If you are getting the same message as the title of this issue then the problem is that your script is not passing the correct set of reference assemblies to the compiler. In general we do not recommend directly invoking the compiler in this way because getting the correct set of references is quite challenging when you take into account all of the scenarios that .NET supports. Instead we strongly recommend that you use an MSBuild file to drive the compiler.

kinglionsz commented 3 years ago

Yes. I understand. Thank you so much. @jaredpar

km-hussain-in commented 3 years ago

@kinglionsz can you explain what problem you are hitting here?

If you are getting the same message as the title of this issue then the problem is that your script is not passing the correct set of reference assemblies to the compiler. In general we do not recommend directly invoking the compiler in this way because getting the correct set of references is quite challenging when you take into account all of the scenarios that .NET supports. Instead we strongly recommend that you use an MSBuild file to drive the compiler.

It would be much easier to teach c# to a beginner if source files could be directly compiled without requiring msbuild.

GeirGrusom commented 3 years ago

It would be much easier to teach c# to a beginner if source files could be directly compiled without requiring msbuild.

Pretty off-topic here but I think it's important:

The c# compiler is called csc.exe and you can invoke it directly. But if you're teaching C# programming and focusing on the command line I think you're just wasting time. Focus on the language and use a toolchain that is easy to set up and get going because the main focus should be on the language itself and not the user interface.

You're never going to complete a task by doing something completely different. The command line offers no specific insights into the C# language or even the compiler itself. You're just showing them a different user interface than the one they would spend 99% of their time in when they are actually using the language.

jaredpar commented 3 years ago

It would be much easier to teach c# to a beginner if source files could be directly compiled without requiring msbuild.

I agree strongly with the principle that it should be possible to build and use single file C# applications without the need for a supporting project file. I dream of a place where we can dotnet run helloworld.cs.

At the same time though it will still require msbuild under the hood. That is because compilation is only one part of the application development experience. Compilation just a process that takes in a set of references and source files and produces a DLL / EXE file. The act of dotnet run though involves a lot more work than that:

  1. Discovering the set of references that are used in a compilation
  2. Discovering the set of source source files used in a compilation
  3. Locating the appropriate dotnet to run the application
  4. Deploying all of the supporting binaries next to the compiled DLL / EXE

These are all responsibilities of the msbuild layer. Hence it's not really possible to remove msbuild from the single file experience because it's pretty integral to it.

What we can do though is remove the project file and have it just be generated behind the scenes in memory to drive the same experience.

km-hussain-in commented 3 years ago

It would be much easier to teach c# to a beginner if source files could be directly compiled without requiring msbuild.

Pretty off-topic here but I think it's important:

The c# compiler is called csc.exe and you can invoke it directly. But if you're teaching C# programming and focusing on the command line I think you're just wasting time. Focus on the language and use a toolchain that is easy to set up and get going because the main focus should be on the language itself and not the user interface.

You're never going to complete a task by doing something completely different. The command line offers no specific insights into the C# language or even the compiler itself. You're just showing them a different user interface than the one they would spend 99% of their time in when they are actually using the language.

I prefer to begin with csc while teaching language basics and then move my students to msbuild. Similarly in Java I don’t begin with maven for teaching basic programming syntax, I introduce it later.

wstaelens commented 2 years ago

After upgrading Visual Studio 2022 17.2.x (latest preview version) to Version 17.3.0 Preview 1.0. I now have the same CS0518: Predefined type 'System.Object' is not defined or imported in my Blazor Server .razor page. I didn't have this in the latest preview version 17.2.x before updating to 17.3.0.

.NET 6 project. Windows 10 x64 pro

jaredpar commented 2 years ago

@wstaelens can you grab a binary log of the build when it fails like that? Generally that error means the underlying build is erroring and not giving the proper references to the compiler. The binlog should help us understand where that error is happening

wstaelens commented 2 years ago

sorry, for the late reply @jaredpar If you can tell me where that log is located then I can give you that part of the log from 4 days ago... (if this is possible).

For some other reasons I had to restart VS several times including my PC and the message went away for now...

jaredpar commented 2 years ago

This log isn't generated by default so it won't be stored anywhere. Its something you have to request be generated.

If it's not reproducing anymore I'm going to close this issue out. If you can reproduce it in the future though please do post here and we'll reactivate and follow up.