-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
It seems that our AOT generated shared library was crashing on a class that we run perfectly fine on Debug configuration. We have some custom dictionaries that allows to create a default value when the key was not found but on release mode it was throwing key not found since it was not respecting the class instance override method
Reproduction Steps
public class OrderedDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary<TKey, TValue>
{
TValue IDictionary<TKey, TValue>.this[TKey key]
{
get
{
Console.WriteLine("OrderedDictionary -> []");
return GetValue(key);
}
set
{
if (!ContainsKey(key))
{
_keys.Add(key);
}
base[key] = value;
}
}
protected virtual TValue GetValue(TKey key)
{
Console.WriteLine("OrderedDictionary -> GetValue");
return base[key];
}
}
public class OrderedDictionaryWithDefault<TKey, TValue> : OrderedDictionary<TKey, TValue>
where TValue : new()
{
public OrderedDictionaryWithDefault()
{
Console.WriteLine("ctor -> OrderedDictionaryWithDefault");
}
protected override TValue GetValue(TKey key)
{
Console.WriteLine("OrderedDictionaryWithDefault -> GetValue");
if (!ContainsKey(key))
{
_keys.Add(key);
base[key] = new TValue();
}
return base.GetValue(key);
}
}
We also have this:
public interface IDictionaryFactory
{
IDictionary<TKey, TValue> Create<TKey, TValue>() where TValue : new();
}
public class OrdereDictionaryFactory : IDictionaryFactory
{
public static OrdereDictionaryFactory Instance { get; } = new OrdereDictionaryFactory();
public IDictionary<TKey, TValue> Create<TKey, TValue>()
where TValue : new()
{
return new OrderedDictionaryWithDefault<TKey, TValue>();
}
}
On some other class type we have this:
public KeyframeNeighborhoodData(IDictionaryFactory dictionaryFactory)
{
this.keyframes = dictionaryFactory.Create<Guid, Keyframe>();
this.knAnchors = dictionaryFactory.Create<Guid, CompleteAnchor>();
}
Our test is very simple:
var kfnData = new KeyframeNeighborhoodData(OrdereDictionaryFactory.Instance);
kfnData.keyframes[id].hasAbsoluteLayoutInfo = true;
Console.WriteLine($"works...");
Expected behavior
The simple test code pass and the override method should be invoked from the class instance instead of the base class
Actual behavior
ctor -> OrderedDictionaryWithDefault
ctor -> OrderedDictionaryWithDefault
OrderedDictionary -> []
OrderedDictionary -> GetValue
Unhandled Exception: System.Collections.Generic.KeyNotFoundException: The given key 'ef188a25-461a-471e-913f-89b01274e231' was not present in the dictionary.
at System.ThrowHelper.ThrowKeyNotFoundExceptionT + 0x2b
at System.Collections.Generic.Dictionary2.get_Item(TKey) + 0x3a at MixedReality.EU.Common.OrderedDictionary2.System.Collections.Generic.IDictionary<TKey,TValue>.get_Item(TKey) + 0x41
at MixedReality.EU.Api.AOT!+0x40a2f4
Regression?
No response
Known Workarounds
Adding an additional constructor:
public KeyframeNeighborhoodData(IDictionary<Guid, Keyframe> keyframes, IDictionary<Guid, CompleteAnchor> knAnchors)
{
this.keyframes = keyframes;
this.knAnchors = knAnchors;
}
and using this:
var kfnData = new KeyframeNeighborhoodData(
OrdereDictionaryFactory.Instance.Create<Guid, KeyframeNeighborhoodData.Keyframe>(),
OrdereDictionaryFactory.Instance.Create<Guid, CompleteAnchor>()
);
Fixed the problem.
Configuration
The IL tools used is this ->7.0.0-RC.1.22363.4
Other information
No response