FsAutoComplete
FsAutoComplete copied to clipboard
Go-to-definition decompiler puts `throw null` in bodies of all members/properties for refs libraries.
This happens on .Net Core / .Net Standard for any symbol which definition is added through reference library (for example netstandard.dll
or System.Runtime
).
Sample for float
:
using System.Globalization;
namespace System
{
public struct Double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, IFormattable
{
public const double Epsilon = 4.94065645841247E-324;
public const double MaxValue = 1.7976931348623157E+308;
public const double MinValue = -1.7976931348623157E+308;
public const double NaN = 0.0 / 0.0;
public const double NegativeInfinity = -1.0 / 0.0;
public const double PositiveInfinity = 1.0 / 0.0;
public int CompareTo(double value)
{
throw null;
}
public int CompareTo(object value)
{
throw null;
}
public bool Equals(double obj)
{
throw null;
}
public override bool Equals(object obj)
{
throw null;
}
public override int GetHashCode()
{
throw null;
}
public TypeCode GetTypeCode()
{
throw null;
}
public static bool IsInfinity(double d)
{
throw null;
}
public static bool IsNaN(double d)
{
throw null;
}
public static bool IsNegativeInfinity(double d)
{
throw null;
}
public static bool IsPositiveInfinity(double d)
{
throw null;
}
public static bool operator ==(double left, double right)
{
throw null;
}
public static bool operator >(double left, double right)
{
throw null;
}
public static bool operator >=(double left, double right)
{
throw null;
}
public static bool operator !=(double left, double right)
{
throw null;
}
public static bool operator <(double left, double right)
{
throw null;
}
public static bool operator <=(double left, double right)
{
throw null;
}
public static double Parse(string s)
{
throw null;
}
public static double Parse(string s, NumberStyles style)
{
throw null;
}
public static double Parse(string s, NumberStyles style, IFormatProvider provider)
{
throw null;
}
public static double Parse(string s, IFormatProvider provider)
{
throw null;
}
bool IConvertible.ToBoolean(IFormatProvider provider)
{
throw null;
}
byte IConvertible.ToByte(IFormatProvider provider)
{
throw null;
}
char IConvertible.ToChar(IFormatProvider provider)
{
throw null;
}
DateTime IConvertible.ToDateTime(IFormatProvider provider)
{
throw null;
}
decimal IConvertible.ToDecimal(IFormatProvider provider)
{
throw null;
}
double IConvertible.ToDouble(IFormatProvider provider)
{
throw null;
}
short IConvertible.ToInt16(IFormatProvider provider)
{
throw null;
}
int IConvertible.ToInt32(IFormatProvider provider)
{
throw null;
}
long IConvertible.ToInt64(IFormatProvider provider)
{
throw null;
}
sbyte IConvertible.ToSByte(IFormatProvider provider)
{
throw null;
}
float IConvertible.ToSingle(IFormatProvider provider)
{
throw null;
}
object IConvertible.ToType(Type type, IFormatProvider provider)
{
throw null;
}
ushort IConvertible.ToUInt16(IFormatProvider provider)
{
throw null;
}
uint IConvertible.ToUInt32(IFormatProvider provider)
{
throw null;
}
ulong IConvertible.ToUInt64(IFormatProvider provider)
{
throw null;
}
public override string ToString()
{
throw null;
}
public string ToString(IFormatProvider provider)
{
throw null;
}
public string ToString(string format)
{
throw null;
}
public string ToString(string format, IFormatProvider provider)
{
throw null;
}
public static bool TryParse(string s, out double result)
{
result = 0.0;
throw null;
}
public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out double result)
{
result = 0.0;
throw null;
}
}
}
Confirmed, if you decompile System.Private.Corelib you can see the actual definitions for those members^
This is because we find the ref assembly instead of the actual implementation assembly. I don't know of any mechanism to find an implementation assembly given a ref assembly, at least not without doing more path probing....
A potential solution to this might be using the new signature-file metadata view coming in FCS 40 for these lookups instead of the ICSharpCode decompiler. We may want to make that an option anyway.
Roslyn has logic for handling this here.