VSF_TYPE_MARKDOWNAfter updating Visual Studio, I run my F# App and it is throwing System.NullReferenceException on the type definition, out of nowhere.
See screenshot
_This issue has been moved from https://developercommunity.visualstudio.com/content/problem/472004/f-throwing-systemnullreferenceexception-out-of-now.html
VSTS ticketId: 803507_
_These are the original issue comments:_
Tony Henrique on 2/27/2019, 05:30 PM (38 hours ago):

Screenshot
Tony Henrique on 2/27/2019, 05:52 PM (38 hours ago):
This is what I have on the Call Stack:
ClassLibrary1.dll!Entidades.Pedido.Equals(object obj) Line 70 F#
Visual Studio Feedback System on 2/27/2019, 06:26 PM (37 hours ago):
We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.
_These are the original issue solutions:_
(no solutions)
Image that won't transfer over:

The Code that causes that is this:
private void Button_Click(object sender, RoutedEventArgs e)
{
// uses the F# library from C#
var pedido = API.Actions.PegaFormPedido(Guid.Parse("4644cf33-06af-44d7-907b-085c2a9b65a3"));// API.Actions.NovoPedido();
// Binds the returned F# object to WPF UI
this.DataContext = pedido;
}
Here is the Call Stack
ClassLibrary1.dll!Entidades.Pedido.Equals(Entidades.Pedido obj) F#
ClassLibrary1.dll!Entidades.Pedido.Equals(object obj) Line 70 F#
mscorlib.dll!object.Equals(object objA, object objB) Unknown
PresentationFramework.dll!System.Windows.Data.BindingExpression.OnDataContextChanged(System.Windows.DependencyObject contextElement) Unknown
PresentationFramework.dll!System.Windows.Data.BindingExpression.HandlePropertyInvalidation(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs args) Unknown
PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.OnPropertyInvalidation(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs args) Unknown
PresentationFramework.dll!System.Windows.Data.BindingExpression.OnPropertyInvalidation(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs args) Unknown
WindowsBase.dll!System.Windows.DependentList.InvalidateDependents(System.Windows.DependencyObject source, System.Windows.DependencyPropertyChangedEventArgs sourceArgs) Unknown
WindowsBase.dll!System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs args) Unknown
WindowsBase.dll!System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex entryIndex, System.Windows.DependencyProperty dp, System.Windows.PropertyMetadata metadata, System.Windows.EffectiveValueEntry oldEntry, ref System.Windows.EffectiveValueEntry newEntry, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType) Unknown
PresentationFramework.dll!System.Windows.TreeWalkHelper.OnInheritablePropertyChanged(System.Windows.DependencyObject d, System.Windows.InheritablePropertyChangeInfo info, bool visitedViaVisualTree) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>._VisitNode(System.Windows.DependencyObject d, bool visitedViaVisualTree) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.VisitNode(System.Windows.FrameworkElement fe, bool visitedViaVisualTree) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.VisitNode(System.Windows.DependencyObject d, bool visitedViaVisualTree) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.WalkLogicalChildren(System.Windows.FrameworkElement feParent, System.Windows.FrameworkContentElement fceParent, System.Collections.IEnumerator logicalChildren) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.WalkFrameworkElementLogicalThenVisualChildren(System.Windows.FrameworkElement feParent, bool hasLogicalChildren) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.IterateChildren(System.Windows.DependencyObject d) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>._VisitNode(System.Windows.DependencyObject d, bool visitedViaVisualTree) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.VisitNode(System.Windows.FrameworkElement fe, bool visitedViaVisualTree) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.VisitNode(System.Windows.DependencyObject d, bool visitedViaVisualTree) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.WalkLogicalChildren(System.Windows.FrameworkElement feParent, System.Windows.FrameworkContentElement fceParent, System.Collections.IEnumerator logicalChildren) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.WalkFrameworkElementLogicalThenVisualChildren(System.Windows.FrameworkElement feParent, bool hasLogicalChildren) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.IterateChildren(System.Windows.DependencyObject d) Unknown
PresentationFramework.dll!System.Windows.DescendentsWalker<System.Windows.InheritablePropertyChangeInfo>.StartWalk(System.Windows.DependencyObject startNode, bool skipStartNode) Unknown
PresentationFramework.dll!System.Windows.FrameworkElement.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e) Unknown
WindowsBase.dll!System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs args) Unknown
WindowsBase.dll!System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex entryIndex, System.Windows.DependencyProperty dp, System.Windows.PropertyMetadata metadata, System.Windows.EffectiveValueEntry oldEntry, ref System.Windows.EffectiveValueEntry newEntry, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType) Unknown
WindowsBase.dll!System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty dp, object value, System.Windows.PropertyMetadata metadata, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType, bool isInternal) Unknown
WindowsBase.dll!System.Windows.DependencyObject.SetValue(System.Windows.DependencyProperty dp, object value) Unknown
PresentationFramework.dll!System.Windows.FrameworkElement.DataContext.set(object value) Unknown
WpfApp1.exe!WpfApp1.MainWindow.Button_Click(object sender, System.Windows.RoutedEventArgs e) Line 36 C#
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) Unknown
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs e) Unknown
PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnClick() Unknown
PresentationFramework.dll!System.Windows.Controls.Button.OnClick() Unknown
PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) Unknown
PresentationCore.dll!System.Windows.UIElement.OnMouseLeftButtonUpThunk(object sender, System.Windows.Input.MouseButtonEventArgs e) Unknown
PresentationCore.dll!System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) Unknown
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) Unknown
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) Unknown
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
PresentationCore.dll!System.Windows.UIElement.ReRaiseEventAs(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args, System.Windows.RoutedEvent newEvent) Unknown
PresentationCore.dll!System.Windows.UIElement.OnMouseUpThunk(object sender, System.Windows.Input.MouseButtonEventArgs e) Unknown
PresentationCore.dll!System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) Unknown
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) Unknown
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) Unknown
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) Unknown
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) Unknown
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() Unknown
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) Unknown
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) Unknown
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel) Unknown
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd, MS.Internal.Interop.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) Unknown
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Unknown
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Unknown
PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) Unknown
PresentationFramework.dll!System.Windows.Application.Run() Unknown
WpfApp1.exe!WpfApp1.App.Main() Unknown
@TonyHenrique You'd need to post the code for Entidades.Pedido to make sense of this.
WPF is calling Pedido.Equals, maybe to check if DataContext did infact change?
I'd say some C# reflection code has created F# objects containing null values.
@dsyme Yes, DataContext is probably null when this is first assigned for example.
My Entidades.Pedido is defined in F#:
[<CLIMutable>]
//[<AddINotifyPropertyChangedInterfaceAttribute>] // Injects INotifyPropertyChanged code into properties at compile time // https://github.com/Fody/PropertyChanged
Pedido =
{
mutable ID: Guid
mutable Numero: string
[<EdgeIn("POSSUI")>]
mutable Cliente: Pessoa
[<EdgeOut("POSSUI")>]
mutable Items: ObservableCollection<ItemPedido>
}
let PegaFormPedido (id:Guid) : Pedido =
let t = typeof<Pedido>
let constructedType = typedefof<Pedido>
let x = Activator.CreateInstance(constructedType)
let x_p = x :?> Pedido
SetProperty constructedType x "ID" (Guid.Parse("6762bad8-086c-4e6a-9abb-6213f0743b0c"))
SetProperty constructedType x "Numero" ("3a+")
x_p
Simple thing to rule out: delete all your bin and obj folders, then rebuild. In case it's an incremental build issue. I've had that happen a few times in the past. No amount of Clean, then Build would fix it. I had to physically delete the bin/obj folders.
I deleted both bin and obj but problem persists.
It only happens after I click the button the second time. First time, everything works as expected. On second click, it gives the Exception:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Call Stack:
ClassLibrary1.dll!Entidades.Pedido.Equals(Entidades.Pedido obj) F#
> ClassLibrary1.dll!Entidades.Pedido.Equals(object obj) Line 70 F#
mscorlib.dll!object.Equals(object objA, object objB) Unknown
PresentationFramework.dll!System.Windows.Data.BindingExpression.OnDataContextChanged(System.Windows.DependencyObject contextElement) Unknown
Ok, does sound like C# creating something null as previously mentioned. I run into this problem sometimes when I let C#-based libs create objects that get passed into F#, such as when deserializing with Newtonsoft.Json.
Maybe this is related to the generic code?
let constructedType = typedefof<Pedido>
let x = Activator.CreateInstance(constructedType)
Given that the C# code is creating a null value, it sounds like the remediation here is to all the appropriate null check in the F# code. I don't think this is an issue in the F# compiler or tools.
From what I know, this null is not being created on my C# code.
Can you give a look?
I created a sample repro, just click the WPF button 3 times and it will throw the Exception:
https://drive.google.com/open?id=1g0TdwvkPsKJWRtHf81kbuuhNtTupQpCB
I could make an even smaller repro:
Create a New F# Console Application (.NET Core), paste this code and run.
open System
module API =
[<CLIMutable>]
type Person = { mutable Name : string }
[<CLIMutable>]
type Invoice = { mutable Customer: Person }
let blow () =
let constructedType = typedefof<Invoice>
let x = Activator.CreateInstance(constructedType)
x
[<EntryPoint>]
let main argv =
let x = blow ()
let eq = x.Equals(x); // This line will throw the Exception
//let res = x.GetHashCode() // This line will throw the Exception
0
Or Create a New F# Class Library (.NET Core), and a C# WPF App, reference the F# Class Library.
In the C# side, this will also throw the Exception in the F# code:
private void Button_Click(object sender, RoutedEventArgs e)
{
var x = API.Actions.blow();
x.Equals(x);
}
I think that this is related to this issue: https://github.com/Microsoft/visualfsharp/issues/1044
Is it possible to add a warning when nulls are not checked when consuming C#?
@TonyHenrique the problem is by using CreateInstance in conjuction with CLIMuteable you circumvent F# type system, creating an invalid record filled with nulls. You could write functions that would return valid default values for each record type, or just use objects here.
BTW using [<CLIMutable>] records for WPF viewmodels is a minefield.
I noticed here that if I add the option keyword to the fields that references other records types, the Exception does not occur, and it works fine:
[<CLIMutable>]
type Person = { mutable Name : string }
[<CLIMutable>]
type Invoice = { mutable Customer: Person option }
Can it be safely used with this code?
let constructedType = typedefof<Invoice>
let x = Activator.CreateInstance(constructedType)
I would like to know how to remove the mutable, and make it work in TwoWay DataBinding in WPF/UWP. Then it would be a cleaner and safer code.
@majocha I don't know how your suggested approach would be possible, because I am trying to write something like a simple Graph ORM and need to use Reflection to dinamically fill the fields at runtime.
@TonyHenrique the problem is by using CreateInstance in conjuction with CLIMuteable you circumvent F# type system, creating an invalid record filled with nulls. You could write functions that would return valid default values for each record type, or just use objects here.
BTW using [ < CLIMutable>] records for WPF viewmodels is a minefield.
You are right. I see now that trying to use F# Records + Fody.INotifyPropertyChanged to interop directly with my old WPF code is not good idea.
Now Reading the F# docs, I see this:
If your F# code has to work closely with the .NET Framework or another object-oriented library, and especially if you have to extend from an object-oriented type system such as a UI library, classes are probably appropriate.
If you are not interoperating closely with object-oriented code, or if you are writing code that is self-contained and therefore protected from frequent interaction with object-oriented code, you should consider using records and discriminated unions.
https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/classes#when-to-use-classes-unions-records-and-structures
On this case, I should use F# Classes instead.
Most helpful comment
Maybe this is related to the generic code?