Author Topic: Playing with C#8 in Framework 4.8  (Read 5825 times)

0 Members and 3 Guests are viewing this topic.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Playing with C#8 in Framework 4.8
« on: July 07, 2023, 11:27:52 PM »
It's a rainy Saturday, so . . .

modified the .csproj file
Code - XML: [Select]
  1.   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
  2.     <DebugSymbols>true</DebugSymbols>
  3.     <OutputPath>bin\x64\Debug\</OutputPath>
  4.     <DefineConstants>DEBUG;TRACE</DefineConstants>
  5.     <DebugType>full</DebugType>
  6.     <PlatformTarget>x64</PlatformTarget>
  7.        
  8.         <!-- <LangVersion>7.3</LangVersion> -->
  9.     <LangVersion>8.0</LangVersion>
  10.     <Nullable>enable</Nullable>
  11.        
  12.     <ErrorReport>prompt</ErrorReport>
  13.   </PropertyGroup>
  14.   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
  15.     <OutputPath>bin\x64\Release\</OutputPath>
  16.     <DefineConstants>TRACE</DefineConstants>
  17.     <Optimize>true</Optimize>
  18.     <DebugType>pdbonly</DebugType>
  19.     <PlatformTarget>x64</PlatformTarget>
  20.        
  21.         <!-- <LangVersion>7.3</LangVersion> -->
  22.     <LangVersion>8.0</LangVersion>
  23.     <Nullable>enable</Nullable>
  24.        
  25.     <ErrorReport>prompt</ErrorReport>
  26.   </PropertyGroup>
  27.  


and had a play . . .

Code - C#: [Select]
  1. public class CommandsTest
  2.    {
  3.       private static readonly Document _doc = CadApp.DocumentManager.MdiActiveDocument;
  4.       private static readonly Database _db = _doc.Database;
  5.       private static readonly Editor _ed = _doc.Editor;
  6.  
  7.       //----Test C# 8 in Framework -----------------------------------------------
  8.       public string? NullableString { get; set; }
  9.       private string _name;
  10.       public string Name
  11.       {
  12.          get => _name;
  13.          set => _name = value ?? throw new ArgumentNullException(nameof(value), "Name cannot be null");
  14.       }
  15.  
  16.       [CommandMethod("Test_cs8")]
  17.       public void Test_cs8()
  18.       {
  19.  
  20.          NullableString = null;
  21.  
  22.          _ed.WriteMessage($"NullableString : {NullableString}\n");
  23.          // If null, give it a value
  24.          NullableString ??= "Phred Qnurks";
  25.          _ed.WriteMessage($"NullableString : {NullableString}\n");
  26.  
  27.          NullableString ??= "Humpty Dumpty";  // this assignment should be ignored
  28.                                               // 'cause NullableString has a value
  29.          _ed.WriteMessage($"NullableString : {NullableString}\n");
  30.          //-------------
  31.  
  32.          List<int> numbers = null;
  33.          int? a = null;
  34.  
  35.          _ed.WriteMessage($"(numbers is null) : {(numbers is null)}\n");
  36.          // expected: true
  37.  
  38.          // if numbers is null, initialize it. Then, add 5 to numbers
  39.          (numbers ??= new List<int>()).Add(5);
  40.          _ed.WriteMessage(string.Join(" ", numbers) + "\n");
  41.          // output: 5
  42.  
  43.          _ed.WriteMessage($"{(numbers is null)} \n");
  44.          // expected: false
  45.  
  46.          _ed.WriteMessage($"(a is null) : {(a is null)} \n");
  47.          // expected: true
  48.  
  49.          _ed.WriteMessage($"(a ?? 3) : {(a ?? 3)}\n");
  50.          // expected: 3 since a is still null
  51.  
  52.  
  53.          int? b = null;
  54.  
  55.          int c = b ?? -1;
  56.  
  57.          _ed.WriteMessage($"value c : {c}\n");
  58.  
  59.  
  60.          Name = "Phred";
  61.          _ed.WriteMessage($"value Name : {Name}\n");
  62.  
  63.       }
  64.    }
  65.  

then opened the beast . . .


Command: netload Assembly file name: "Teststuff.dll"
Command:
Teststuff loaded.  : Right-Click for Menu.
Command: TEST_CS8
NullableString :
NullableString : Phred Qnurks
NullableString : Phred Qnurks
(numbers is null) : True
5
False
(a is null) : True
(a ?? 3) : 3
value c : -1
value Name : Phred



ref :
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8927
  • AKA Daniel
Re: Playing with C#8 in Framework 4.8
« Reply #1 on: July 07, 2023, 11:35:04 PM »
Like a whole new language!  Spaceship operator?

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Re: Playing with C#8 in Framework 4.8
« Reply #2 on: July 07, 2023, 11:50:21 PM »

the null conditional operator '?'  in C# (also known as null propagation operator or the Elvis operator).

The three-way comparison operator '<=>' is called a spaceship operator from C++

?? and ??= operators - the null-coalescing operators in C# - not sure if they have geek alias names
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Re: Playing with C#8 in Framework 4.8
« Reply #3 on: July 07, 2023, 11:58:25 PM »

I'm working through the C# 8 updates
Then C# 9  ; .net 5
Then C# 10 ; .net 6
Then C# 11 ; .net 7

I had a play with .NET 8 preview in the VS2022 17.7.0 preview 2.0 last night.
the new net build won't be released till November.
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Re: Playing with C#8 in Framework 4.8
« Reply #4 on: July 08, 2023, 06:14:29 PM »
Because of AutoDesk's previous decision to only support the .net Framework I have about 5 years of C# versions to catch up on. Rightly or not, I had taken the attitude "we can't use it, so I won't attempt to grok it" I hope that attempt to keep some spare brain capacity doesn't bite me in the arse.

Regarding the use of Nullable reference types :

https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references
https://learn.microsoft.com/en-us/dotnet/csharp/nullable-migration-strategies

Be aware about blindly adding  <Nullable>enable</Nullable> to the .csprog project file
"The new features that protect against throwing a System.NullReferenceException can be disruptive when turned on in an existing codebase:
  • All explicitly typed reference variables are interpreted as non-nullable reference types.
  • The meaning of the class constraint in generics changed to mean a non-nullable reference type.
  • New warnings are generated because of these new rules.

At least the compiler will throw warnings.

I think I'll take a couple weeks to re-read all this, it's too important to stuff-up.

Starting in .NET 6, ( C#10 ) they're enabled by default for new projects.

The first decision to make is 'do I want to use Nullable reference types'

Because of the language history, the decision to use the same syntax for value types and reference types changes the behavior of the language for reference types. Before C# 8, all reference types were nullable. They were however declared without a question mark:

Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8927
  • AKA Daniel
Re: Playing with C#8 in Framework 4.8
« Reply #5 on: July 09, 2023, 02:00:10 AM »
I’m reading it as a good thing. The compiler will force you to check for null, right?
C++ is getting better at warning about null, though the static analysis isn’t perfect.  Example, if I use a getter, the compiler sometimes whines 

Code - C++: [Select]
  1. wxWindow* PyCAdUiPaletteImpl::thiswindow(const std::source_location& src /*= std::source_location::current()*/) const
  2. {
  3.     if (m_thiswin == nullptr)
  4.         throw PyNullObject(src);
  5.     return m_thiswin;
  6. }
  7.  


 

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Re: Playing with C#8 in Framework 4.8
« Reply #6 on: July 09, 2023, 03:14:41 AM »
I’m reading it as a good thing. The compiler will force you to check for null, right?
C++ is getting better at warning about null, though the static analysis isn’t perfect.  Example, if I use a getter, the compiler sometimes whines 
>>> . . .

Yes, that's the way I see it too Daniel.

I added the 'enable' flag to one of my test projects.
Scared me a little to see the warnings that the compiler threw up regarding 'possible null' values.
. . . but easily fixed I think

This throws on acLayout
Code - C#: [Select]
  1. Layout acLayout = tr.GetObject(objID, OpenMode.ForRead) as Layout;
and this on appContextMnuItem
Code - C#: [Select]
  1. AppContextMenuItem appContextMnuItem = mnuItem as AppContextMenuItem;
Warning   CS8602   Dereference of a possibly null reference.   

While these are ok:
Code - C#: [Select]
  1. Layout acLayout = (Layout)tr.GetObject(objID, OpenMode.ForRead);
Code - C#: [Select]
  1. AppContextMenuItem appContextMnuItem = (AppContextMenuItem)mnuItem ;

So it looks like we'll make sure of casting.


another:
Code - C#: [Select]
  1. PromptPointResult pointResult = default;
for pointResult
Warning   CS8600   Converting null literal or possible null value to non-nullable type.   

« Last Edit: July 09, 2023, 03:19:07 AM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8927
  • AKA Daniel
Re: Playing with C#8 in Framework 4.8
« Reply #7 on: July 09, 2023, 04:05:10 AM »
 I don’t know the consequences of using a C style cast. The ‘as’ with a null check seems better

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Re: Playing with C#8 in Framework 4.8
« Reply #8 on: July 09, 2023, 06:15:57 AM »
I don’t know the consequences of using a C style cast. The ‘as’ with a null check seems better

yes,
On failure, the as (soft cast) returns null,
and the (hard) cast throws an exception,
so the issue has to be handled either way.

A guard clause on the 'as' might be cleaner and faster.  Testing will tell.

I'd bet a couple pennys 'most' people would just ignore the compiler warnings saying "I've never had a problem before, so . . . "


Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

BlackBox

  • King Gator
  • Posts: 3770
Re: Playing with C#8 in Framework 4.8
« Reply #9 on: July 11, 2023, 02:00:17 PM »
I don’t know the consequences of using a C style cast. The ‘as’ with a null check seems better

yes,
On failure, the as (soft cast) returns null,
and the (hard) cast throws an exception,
so the issue has to be handled either way.

A guard clause on the 'as' might be cleaner and faster.  Testing will tell.

I'd bet a couple pennys 'most' people would just ignore the compiler warnings saying "I've never had a problem before, so . . . "

I usually direct cast in lieu of using 'as' where my code is based on selection sets; the Type is already accounted for and a cast-specific handling for Null or Exception isn't typically needed (in addition to the method's try catch block).
"How we think determines what we do, and what we do determines what we get."

gile

  • Gator
  • Posts: 2522
  • Marseille, France
Re: Playing with C#8 in Framework 4.8
« Reply #10 on: August 07, 2023, 01:36:21 PM »
Hi,

Thanks Kerry.
Playing with pattern matching.

Example without pattern matching (C# 6):
Code - C#: [Select]
  1.         private static void SetColor(Entity entity)
  2.         {
  3.             int colorIndex = 256;
  4.             if (entity is BlockReference)
  5.             {
  6.                 var b = (BlockReference)entity;
  7.                 if (b.Position.Z == 0.0)
  8.                 {
  9.                     colorIndex = 31;
  10.                 }
  11.             }
  12.             else if (entity is Dimension)
  13.             {
  14.                 var d = (Dimension)entity;
  15.                 if (d.DimensionText != "")
  16.                 {
  17.                     colorIndex = 141;
  18.                 }
  19.             }
  20.             else if (entity is DBPoint)
  21.             {
  22.                 colorIndex = 241;
  23.             }
  24.             entity.ColorIndex = colorIndex;
  25.         }

Witch C# 7 pattern matching:
Code - C#: [Select]
  1.        private static void SetColor(Entity entity)
  2.         {
  3.             int colorIndex;
  4.             switch (entity)
  5.             {
  6.                 case BlockReference b when b.Position.Z != 0.0:
  7.                     colorIndex = 31;
  8.                     break;
  9.                 case Dimension d when d.DimensionText != "":
  10.                     colorIndex = 141;
  11.                     break;
  12.                 case DBPoint _:
  13.                     colorIndex = 241;
  14.                     break;
  15.                 default:
  16.                     colorIndex = 256;
  17.                     break;
  18.             }
  19.             entity.ColorIndex = colorIndex;
  20.         }

With C# 8 pattern matching:
Code - C#: [Select]
  1.         private static void SetColor(Entity entity) =>
  2.             entity.ColorIndex = entity switch
  3.             {
  4.                 BlockReference b when b.Position.Z != 0.0 => 31,
  5.                 Dimension d when d.DimensionText != "" => 141,
  6.                 DBPoint _ => 241,
  7.                 _ => 256
  8.             };

With F# 1.0:
Code - F#: [Select]
  1. let setColor (entity: Entity) =
  2.     entity.ColorIndex <-
  3.         match entity with
  4.         | :? BlockReference as b when b.Position.Z <> 0.0 -> 31
  5.         | :? Dimension as d when d.DimensionText <> "" -> 141
  6.         | :? DBPoint -> 241
  7.         | _ -> 256

Life imitates art.
C# imitates F#.
« Last Edit: August 08, 2023, 11:44:08 AM by gile »
Speaking English as a French Frog

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Re: Playing with C#8 in Framework 4.8
« Reply #11 on: August 07, 2023, 06:13:04 PM »
Hi Gilles,
Yes, It's very nice.
Unfortunately my old brain stutters with F#.

With any 'luck' we'll all be writing code like your With C# 8 pattern matching: by this time next year   :wink:

I've signed up for the Alpha/Beta testing for AC2025 so I can't say much more about the planned specifics, but I have my Windows Sandbox ready for testing when the revevant Alpha/Beta arrives.

Meanwhile, all we can do is to become familiar with the new .NET builds ( as we've been doing here )

added: Those are excellent examples of the functionality . . . well worth the study for anyone.
Thanks,
« Last Edit: August 07, 2023, 06:17:28 PM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Re: Playing with C#8 in Framework 4.8
« Reply #12 on: August 07, 2023, 10:38:41 PM »
For interests sake, this is the de-compiled code of the  SetColor Method using C# 8 pattern matching:,
just to show how VS handles the pretty switch statement :)

Please ignore the variable names used, they are assigned by my Reflector according to the Type of the value

I think that this is a perfect example of how making significant savings in code time may not reduce the actual compiled code.
. . . but the original source sure IS pretty to read.

Code - C#: [Select]
  1. [NullableContext(1)]
  2. private static void SetColor(Entity entity)
  3. {
  4.     int num;
  5.     Entity entity2 = entity;
  6.     Entity entity3 = entity;
  7.     if (1 == 0)
  8.     {
  9.     }
  10.     BlockReference reference2 = entity3 as BlockReference;
  11.     if (reference2 != null)
  12.     {
  13.         if (reference2.Position.Z != 0.0)
  14.         {
  15.             num = 0x1f;
  16.             goto TR_0001;
  17.         }
  18.     }
  19.     else
  20.     {
  21.         Dimension dimension2 = entity3 as Dimension;
  22.         if (dimension2 != null)
  23.         {
  24.             if (dimension2.DimensionText != "")
  25.             {
  26.                 num = 0x8d;
  27.                 goto TR_0001;
  28.             }
  29.         }
  30.         else if (entity3 is DBPoint)
  31.         {
  32.             num = 0xf1;
  33.             goto TR_0001;
  34.         }
  35.         else if (entity3 == null)
  36.         {
  37.             if (1 == 0)
  38.             {
  39.             }
  40.             <PrivateImplementationDetails>.ThrowInvalidOperationException();
  41.             goto TR_0001;
  42.         }
  43.     }
  44.     num = 0x100;
  45. TR_0001:
  46.     if (1 == 0)
  47.     {
  48.     }
  49.     entity2.ColorIndex = num;
  50. }
  51.  
« Last Edit: August 07, 2023, 10:46:17 PM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Re: Playing with C#8 in Framework 4.8
« Reply #13 on: August 07, 2023, 11:29:29 PM »
For anyone who wants to play, this is one way to call it :

Code - C#: [Select]
  1.      [CommandMethod("SetColor")]
  2.      public static void SetColor()
  3.      {
  4.         var doc = CadApp.DocumentManager.MdiActiveDocument;        
  5.  
  6.         var result = doc.Editor.GetEntity("Select Entity");
  7.         if (result.Status != PromptStatus.OK)
  8.            return;  
  9.  
  10.         using (var tr = new OpenCloseTransaction())
  11.         {
  12.            var ent = (Entity)tr.GetObject(result.ObjectId,
  13.               OpenMode.ForWrite, false, false);
  14.            SetColor( ent );
  15.  
  16.            tr.Commit();
  17.         }
  18.      }
  19.  
  20.  
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

57gmc

  • Bull Frog
  • Posts: 373
Re: Playing with C#8 in Framework 4.8
« Reply #14 on: August 08, 2023, 01:53:03 PM »

I'm working through the C# 8 updates
Then C# 9  ; .net 5
Then C# 10 ; .net 6
Then C# 11 ; .net 7

I had a play with .NET 8 preview in the VS2022 17.7.0 preview 2.0 last night.
the new net build won't be released till November.
I was searching on this subject and found this interesting table.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Re: Playing with C#8 in Framework 4.8
« Reply #15 on: August 09, 2023, 11:35:31 PM »
FWIW :
C# 11 is as far as I've gone.

No Blow-Ups yet . . . but my testing has been pretty simple, so far.
Perhaps take care not to use on production code !!

Using Microsoft Visual Studio Community 2022 (64-bit) - Preview
Version 17.8.0 Preview 1.0

My current .csproj file
The references to NUnit will be removed tonight

Code - XML: [Select]
  1. <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  2.   <Import Project="..\packages\NUnit.3.13.3\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.13.3\build\NUnit.props')" />
  3.   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  4.   <PropertyGroup>
  5.     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
  6.     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
  7.     <ProjectGuid>{BCA3F716-BC8B-4DB0-B38E-6DB783DD0576}</ProjectGuid>
  8.     <OutputType>Library</OutputType>
  9.     <AppDesignerFolder>Properties</AppDesignerFolder>
  10.     <RootNamespace>TestStuff_230711</RootNamespace>
  11.     <AssemblyName>TestStuff_230711</AssemblyName>
  12.     <TargetFrameworkVersion>v4.8.1</TargetFrameworkVersion>
  13.     <FileAlignment>512</FileAlignment>
  14.     <Deterministic>true</Deterministic>
  15.     <TargetFrameworkProfile />
  16.     <NuGetPackageImportStamp>
  17.     </NuGetPackageImportStamp>
  18.   </PropertyGroup>
  19.   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  20.     <DebugSymbols>true</DebugSymbols>
  21.     <DebugType>full</DebugType>
  22.     <Optimize>false</Optimize>
  23.     <DefineConstants>DEBUG;TRACE</DefineConstants>
  24.     <ErrorReport>prompt</ErrorReport>
  25.     <WarningLevel>4</WarningLevel>
  26.     <StartAction>Program</StartAction>
  27.     <StartProgram>C:\Program Files\Autodesk\AutoCAD 2023\acad.exe</StartProgram>
  28.     <StartArguments>/nologo /b "start.scr"</StartArguments>
  29.  
  30. <!-- revised kdub -->
  31.     <OutputPath>bin\x64\Debug\</OutputPath>
  32.     <PlatformTarget>x64</PlatformTarget>
  33.     <!-- <LangVersion>7.3</LangVersion> -->
  34.     <!-- <LangVersion>8.0</LangVersion> -->
  35.     <LangVersion>11.0</LangVersion>
  36.     <Nullable>enable</Nullable>
  37. <!-- revised kdub -->
  38.  
  39.     <DocumentationFile>bin\x64\Debug\TestStuff_230711.xml</DocumentationFile>
  40.   </PropertyGroup>
  41.   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  42.     <DebugType>pdbonly</DebugType>
  43.     <Optimize>true</Optimize>
  44.     <DefineConstants>TRACE</DefineConstants>
  45.     <ErrorReport>prompt</ErrorReport>
  46.     <WarningLevel>4</WarningLevel>
  47.  
  48. <!-- revised kdub -->
  49.     <OutputPath>bin\x64\Release\</OutputPath>
  50.     <PlatformTarget>x64</PlatformTarget>
  51.     <!-- <LangVersion>7.3</LangVersion> -->
  52.     <!-- <LangVersion>8.0</LangVersion> -->
  53.     <LangVersion>11.0</LangVersion>
  54.     <Nullable>enable</Nullable>
  55. <!-- revised kdub -->
  56.  
  57.   </PropertyGroup>
  58.   <ItemGroup>
  59.     <Reference Include="AcCoreMgd">
  60.       <HintPath>..\..\..\..\..\Work\ObjectARX_2023\inc\AcCoreMgd.dll</HintPath>
  61.       <Private>False</Private>
  62.     </Reference>
  63.     <Reference Include="AcDbMgd">
  64.       <HintPath>..\..\..\..\..\Work\ObjectARX_2023\inc\AcDbMgd.dll</HintPath>
  65.       <Private>False</Private>
  66.     </Reference>
  67.     <Reference Include="acdbmgdbrep">
  68.       <HintPath>..\..\..\..\..\Work\ObjectARX_2023\inc\acdbmgdbrep.dll</HintPath>
  69.       <Private>False</Private>
  70.     </Reference>
  71.     <Reference Include="AcMgd">
  72.       <HintPath>..\..\..\..\..\Work\ObjectARX_2023\inc\AcMgd.dll</HintPath>
  73.       <Private>False</Private>
  74.     </Reference>
  75.     <Reference Include="nunit.framework, Version=3.13.3.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
  76.       <HintPath>..\packages\NUnit.3.13.3\lib\net45\nunit.framework.dll</HintPath>
  77.     </Reference>
  78.     <Reference Include="System" />
  79.     <Reference Include="System.Core" />
  80.     <Reference Include="System.Xml.Linq" />
  81.     <Reference Include="System.Data.DataSetExtensions" />
  82.     <Reference Include="Microsoft.CSharp" />
  83.     <Reference Include="System.Data" />
  84.     <Reference Include="System.Net.Http" />
  85.     <Reference Include="System.Xml" />
  86.   </ItemGroup>
  87.   <ItemGroup>
  88.     <Compile Include="Initialization.cs" />
  89.     <Compile Include="PathNetCore.cs" />
  90.     <Compile Include="Test_cs08_11.cs" />
  91.     <Compile Include="Properties\AssemblyInfo.cs" />
  92.   </ItemGroup>
  93.   <ItemGroup>
  94.     <None Include="packages.config" />
  95.     <None Include="start.scr">
  96.       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  97.     </None>
  98.   </ItemGroup>
  99.   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  100.   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
  101.     <PropertyGroup>
  102.       <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
  103.     </PropertyGroup>
  104.     <Error Condition="!Exists('..\packages\NUnit.3.13.3\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.13.3\build\NUnit.props'))" />
  105.   </Target>
  106. </Project>
  107.  
  108.  
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Re: Playing with C#8 in Framework 4.8
« Reply #16 on: August 10, 2023, 07:43:33 PM »
Testing concepts in LinqPad for language changes.

Beginning with C# 11, the interpolated expressions can include newlines.
The text between the { and } must be valid C#, therefore it can include newlines that improve readability.

example of a switch statement in an Interpolated string . . eminently readable !

Of course, the return value of the switch statement could be passed to a layer-changing statement.

« Last Edit: August 10, 2023, 07:46:42 PM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.