dotnet / dotnet-api-docs

.NET API reference documentation (.NET 5+, .NET Core, .NET Framework)
https://docs.microsoft.com/dotnet/api/
Other
722 stars 1.56k forks source link

Example code has runtime error #1741

Open ackerman76 opened 5 years ago

ackerman76 commented 5 years ago

[System.ArgumentNullException: Value cannot be null. Parameter name: key] at System.Runtime.CompilerServices.ConditionalWeakTable`2.TryGetValue(TKey key, TValue& value)

line: else if (cwt.TryGetValue(mc2, out data))


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

rpetrusha commented 5 years ago

Thanks for pointing this out, @ackerman76. The ConditionalWeakTable<TKey,TValue>.TryGetValue method documents the ArgumentNullException, but this example nevertheless passes a null value to the method. It also does a very poor job of demonstrating the type. We'll replace it with a new example in an upcoming sprint.

sungam3r commented 3 years ago

Moreover, example here even does not compile:

namespace ConsoleApp3
{
    using System;
    using System.Runtime.CompilerServices;

    public class Example
    {
        public static void Main()
        {
            var mc1 = new ManagedClass();
            var mc2 = new ManagedClass();
            var mc3 = new ManagedClass();

            var cwt = new ConditionalWeakTable<ManagedClass, ClassData>();
            cwt.Add(mc1, new ClassData());
            cwt.Add(mc2, new ClassData());
            cwt.Add(mc3, new ClassData());

            var wr2 = new WeakReference(mc2);
            mc2 = null;

            GC.Collect();

            ClassData data = null;

            if (wr2.Target == null)
                Console.WriteLine("No strong reference to mc2 exists.");
            else if (cwt.TryGetValue(wr2.Target, out data))             <----------CS1503 Argument 1: cannot convert from 'object' to 'ConsoleApp3.ManagedClass'

                Console.WriteLine("Data created at {0}", data.CreationTime);
            else
                Console.WriteLine("mc2 not found in the table.");
        }
    }

    public class ManagedClass
    {
    }

    public class ClassData
    {
        public DateTime CreationTime;
        public object Data;

        public ClassData()
        {
            CreationTime = DateTime.Now;
            this.Data = new object();
        }
    }
    // The example displays the following output:
    //       No strong reference to mc2 exists.

}
sungam3r commented 3 years ago

And finally it shows different output 😕 after fixing else if (cwt.TryGetValue((ManagedClass)wr2.Target, out data)):

Data created at 07.11.2020 14:32:29

My project:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

</Project>

It seems to me that the example does not work at all.

manuc66 commented 3 years ago

Hi @sungam3r

it seems that splitting the main in two function show the correct output :

  class Program
    {
        static void Main(string[] args)
        {
            var cwt = new ConditionalWeakTable<ManagedClass, ClassData>();
            WeakReference wr2 = Init(cwt);

            GC.Collect();

            ClassData data = null;

            if ( !(wr2.Target is ManagedClass b))
            {
                Console.WriteLine("No strong reference to mc2 exists.");
            }
            else
            {
                if (cwt.TryGetValue(b, out data))
                    Console.WriteLine("Data created at {0}", data.CreationTime);
                else Console.WriteLine("mc2 not found in the table.");
            }
        }

        private static WeakReference Init(ConditionalWeakTable<ManagedClass, ClassData> cwt)
        {
            var mc1 = new ManagedClass();
            var mc2 = new ManagedClass();
            var mc3 = new ManagedClass();

            cwt.Add(mc1, new ClassData());
            cwt.Add(mc2, new ClassData());
            cwt.Add(mc3, new ClassData());

            var wr2 = new WeakReference(mc2);
            mc2 = null;
            return wr2;
        }
    }
    public class ManagedClass
    {
    }

    public class ClassData
    {
        public DateTime CreationTime;
        public object Data;

        public ClassData()
        {
            CreationTime = DateTime.Now;
            this.Data = new object();
        }
    }

And I got :

No strong reference to mc2 exists.

sungam3r commented 3 years ago

The question remains - why doesn't the first example work (both debug and release)?