Why is float.IsFinite “not defined” in Unity? - c#

When I use float.IsFinite(float f) in a C# shell, I have no problems. However, when I use it in the context of Unity, I get an error alleging that it is not defined:
Here is the relevent code:
public static bool IsFinite(Unit u) => float.IsFinite(u.blocks);
Unit is a struct in which I wrote the above line.
My question is: why does this error appear and how can I fix it?

float.IsFinite exists in .NET 5, .NET Standard 2.1 and .NET Core 2.1. However Unity supports neither of those frameworks, just .NET Standard 2.0. This is why you cannot use the function here.
However it´s easy to create a workaround for the lack of that function:
public static bool IsFinite(Unit u) => !float.IsInfinity(u.blocks)
There´s an angoing discussion at Unitity support forum about .NET 5

Related

XmlSerializer behaves different with a property's private getter on .net framework and .net core

I've consumed a third party nuget package which supported .net core and .net framework (.net standard).
My project was a .net framework 4.62 project and when I've used that third party, I've received an exception from the XmlSerializer.
The problem was due to a private getter in a property.
Only public properties and fields can be serialized. Properties must have public accessors (get and set methods). If you need to serialize non-public data, use the BinaryFormatter class rather than XML serialization.
Full Source
After receiving that error, I tried to open a .net core 2.2 project, consumed the same third party nuget and saw that the same code worked there.
He is a small example of code that reproduces the issue:
public class Test
{
public string TestProp { private get; set; }
}
// Exception on .net 462 and works on .net core 2.2
var serializer = XmlSerializer.FromTypes(new[] { typeof(Test) });
So, is this a bug on the .net core implementation or a feature?
Is there anything I can do rather to support this on .net framework without forking the repo and fixing the code?
The "bug" here is that it fails at a different time; on net462 it fails during FromTypes; on netcoreapp2.2 and netcoreapp3.0, it fails during the Serialize, with:
System.InvalidOperationException: There was an error generating the XML document.
---> System.MethodAccessException: Attempt by method 'Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterTest.Write2_Test(System.String, System.String, Test, Boolean, Boolean)' to access method 'Test.get_TestProp()' failed
So ... it really isn't worth worrying about, IMO. There is no real feature difference, by which I mean: it isn't going to work either way. So just... don't do that?
But: you could log it as a bug on github, and even submit a PR so that it fails earlier, if you really want.
That said: if you add:
public bool ShouldSerializeTestProp() => false;
then it will actually work on netcoreapp2.2 and netcoreapp3.0, which is... nice I guess? And could even be considered a reason not to change the new behavior.

Marshal.GetFunctionPointerForDelegate works in .NET Core, but not in .NET Framework

I am testing an SDK written in C#, that came with a demo console application written in .NET Core 2.0. I am trying to make a copy of that application in WPF and leave code the same as much as possible. I get this exception in a method call to the SDK API that adds certain callbacks: Cannot marshal 'parameter #3': Generic types cannot be marshaled. This is from a call to Marshal.GetFunctionPointerForDelegate inside their method. I didn't change any of the code, and it is working in their demo app and throwing an exception in mine. Here is the method call:
_tracking_callback_id =
video_worker.addTrackingCallback(
TrackingCallback,
this);
and here is the callback itself as defined in their API:
public delegate void TrackingCallback(int stream_id, int frame_id, List<RawSample> samples, List<bool> samples_weak, List<float> samples_quality, object userdata);
This also happens when I make a .NET Framework console application copy of their demo, so that indicates it has something to do with .NET Core, but I'm not sure what.

How can I this fix covariance issue with Action on .NET 2?

I need to create a covariant interface with a method that takes a delegate with covariant generic parameter. Here's the code sample under question:
interface IExample<out T1>
{
void ExampleMethod(Action<T1> someAction);
}
On Mono/ .NET 4 profile it compiles OK (tested it in Xamarin studio). However, on .NET 2 (which I'm forced to use since I'm using Unity game engine), I get the following error:
error CS1961: The covariant type parameter 'T1' must be invariantly valid on `CovarianceExample.IExample.ExampleMethod(System.Action)'
Why does this error occur in early .Net versions? How can I fix it?
Why does this error occur in early .Net versions?
Because Action wasn't contravariant in .NET 2.0 (or 3.5).
How can I fix it?
Don't use .NET 2.0 :) I thought that modern versions of Unity were based on more recent versions of Mono anyway - perhaps an upgrade is available?
Alternatively, you could declare your own ContravariantAction delegate:
public delegate void ContravariantAction<in T>(T value);
I haven't tried doing so against .NET 2.0, but I believe the appropriate attributes were already present, and at least the MS .NET implementation supported generic variance - it just wasn't exposed in C# or used in the BCL.

Using LinqBridge in .Net2.0 Website

has anyone been able to use Linqbridge on a .Net 2.0 Website?
I have no problem using it in a normal .Net 2.0 console, but when I use the methods in the website,
I get
Feature 'extension method' cannot be used because it is not part of the ISO-2 C# language specification
I think the error message is pretty clear. Extension methods aren't supported in 2.0. If you want to use an extension method in 2.0, you'd need to modify it by removing the this and call it explicitly.
If you had:
public static class ExtensionMethods {
public static bool IsOdd(this int x) {
return x % 2 != 0;
}
}
Then ExtensionMethods and code like number.IsOdd() won't compile.
You'd need to remove the this in the IsOdd method signature and call it as ExtensionMethods.IsOdd(number) to get it to work under 2.0.
If I recall correctly, that's the approach the authors of LinqBridge used.
Hope that helps.
Maybe you're confusing .NET and C# versions. LINQBridge supports .NET 2.0, but you still need C# 3.0 or later (i.e. VS2008 or later) to compile code with extension method or LINQ syntax sugar. Once compiled, the assembly runs without issue on .NET 2.0 runtimes. That's the benefit of LINQBridge.

Reflect specific framework version?

Using Mono.Cecil
if (MethodDefinition.ReturnType == AssemblyDefinition.MainModule.Import(typeof(string)))
Is failing because the assembly I reading is .net 2 but my program is .net 4. So it is trying to compare string v2 and string v4 so it will never be equal. How can I get the string from v2 without building my program with .net 2?
Your question is similar to this one
In short, you should be able to get the string type with this :
AssemblyDefinition.MainModule.TypeSystem.String

Categories

Resources