decimal extension method error after .net core 2.0 update - .net-core-2.0

I have following extension methods class for doubles and decimals.
The compiler gives me an error for the call of
number.Round(2)
number.Round(3)
within the decimal methods but does not complain about the same methods for the double values.
Any idea why?
Here is the code... easy to reproduce...
public static class NumberExtensions
{
public static double Round(this double number, int decimals)
{
return Math.Round(number, decimals);
}
public static double Round3(this double number)
{
return number.Round(3);
}
public static double Round2(this double number)
{
return number.Round(2);
}
public static decimal Round(this decimal number, int decimals)
{
return Math.Round(number, decimals);
}
public static decimal Round3(this decimal number)
{
return number.Round(3);
}
public static decimal Round2(this decimal number)
{
return number.Round(2);
}
}

The reported error is:
Error CS0176 Member 'decimal.Round(decimal)' cannot be accessed with
an instance reference; qualify it with a type name instead
Possible cause & solution: Error with rounding extension on decimal - cannot be accessed with an instance reference; qualify it with a type name instead
Update:
with .net core version < 2.0, the following statment:
decimal.Round(3);
Error CS0117 'decimal' does not contain a definition for 'Round'
but with .net core 2.0 its valid statement since it cover much more of .NET Framework compared to prior .net core releases,
below quoted from https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-net-core-2-0/ :
We have more than doubled the set of available APIs in .NET Standard
from 13k in .NET Standard 1.6 to 32k in .NET Standard 2.0. Most of the
added APIs are .NET Framework APIs

Okey got it.
In .NET Core there has been added a static method in decimal also naming "Round"... so that's the conflict.

Related

Can a managed ref-class directly implement a COM interface?

Is there a built-in way to allow a managed ref-class to implement and expose a COM inerface that is safely callable from native code?
Looking at the C# side, this is easily done by decorating the target interface with the proper COM-interop attributes, for example:
Native Interface
interface ISampleGrabberCB: public IUnknown
{
virtual STDMETHODIMP SampleCB( double SampleTime, IMediaSample *pSample ) = 0;
virtual STDMETHODIMP BufferCB( double SampleTime, BYTE *pBuffer, long BufferLen ) = 0;
};
static const IID IID_ISampleGrabberCB = { 0x0579154A, 0x2B53, 0x4994,
{ 0xB0, 0xD0, 0xE7, 0x73, 0x14, 0x8E, 0xFF, 0x85 } };
Managed Equivalent Interface
[Guid("0579154A-2B53-4994-B0D0-E773148EFF85")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[SuppressUnmanagedCodeSecurity]
public interface ISampleGrabberCB {
int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen);
int SampleCB(double SampleTime, IMediaSample pSample);
}
Once this declaration is done, through the magic of P-Invoke you can do something like this:
public class FooClass : ISampleGrabberCB {
int ISampleGrabberCB.BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen) {
Console.WriteLine("BufferCB called");
}
int ISampleGrabberCB.SampleCB(double SampleTime, IMediaSample pSample) {
Console.WriteLine("SampleCB called");
}
public void SomeMethod(IBaseFilter aDirectShowFilter) {
ISampleGrabber sampleGrabber = (ISampleGrabber)aDirectShowFilter;
// By the magic of PInvoke, this is possible and works!
// ISampleGrabber->SetCallback() is expecting an ISampleGrabberCB* COM interface
// After the following line, native code is able to callback safely
// into our managed code
sampleGrabber.SetCallback(this, 0);
}
}
Is there a way to mimic this behavior on C++/CLI?
Evidently, the Interop plumbing to make this possible exists as it is used by C#. Furthermore, the compiler could generate the necessary managed interface from inspecting the available native interfaces (I still think we would need to provide the relevant Guids, as this is not an attribute within the native interface)
I just got curious about this topic and played around and I found out some minor differences:
I have IVI-COM class library on my PC, and always wanted to try to interface some of them, although the IVI also has .Net interfaces so it does not make too much sense...
I started with C#, where we get good IntelliSense support. I have added the necessary references and added a class to my project. With the object browser we can select an interface.
public class MyDmm : IIviDmmMultiPoint
{
}
After that just use IntelliSense (Ctrl-.) to add the ‘using’ statement and let them make the necessary properties and methods for us.
using Ivi.Dmm.Interop;
///...
public int Count
{
get
{
throw new NotImplementedException();
}
///...
So now we need the C++-CLI dialect :) Which is as follows:
using namespace IviDmmLib;
///...
public ref class Dmm : IIviDmmMultiPoint
{
Note that the name used by the using statement is different, we can obtain this by selecting the reference at the Solution Explorer and check the name shown at the ‘Properties’ below.
I did not fully complete the experiment but I saw that the COM library was x64 bit, so we may compile the project for the same.
Further interesting readings:
Windows Runtime C++ Template Library
Please, give me feedback if you find some more differences, so we can put them here too.

How to use the foxtools.fll in Winforms?

I have been working in VFP to WPF migration project.While converting the code encountered "foxtools.fll" in foxpro code. I have searched alot on google.
Can any one tell me the use of foxtools.fll? How can we use them in C# ?
I believe many of those elements are already available within C# to some extent. What you may want to do is create your own C# static class and have the functions by the same name reference as they are in VFP, then call with the same parameters as if from VFP, but handle based on C#... Something like
public static class FoxTools
{
// since DriveType is a class, changed method to GetDriveType
public static DriveType GetDriveType( string DriveLetterToTest )
{
Sample code to detect drive types
http://stackoverflow.com/questions/4396634/how-can-i-determine-if-a-given-drive-letter-is-a-local-mapped-usb-drive/4396692#4396692
}
public static string DefaultExt( string ThisFileName, string TryThisExt )
{
if( Path.GetExtension( ThisFileName ).Length > 0
return ThisFileName;
return ThisFileName + TryThisExt;
}
public static string ForceExt( string ThisFileName, string ForceThisExt )
{
return Path.GetFileNameWithoutExtension( ThisFileName ) + ForceThisExt;
}
public static string ForcePath( string ThisFileName, string ForceThisPath )
{
return ForceThisPath + Path.GetFileName( ThisFileName );
}
// many others simple to get to, looking at the "Path." object reference for things
// associated with file names, paths, extensions, etc..
}
Note, you don't have to do EVERY function, just those that you are actually utilizing from the FoxTools.fll. After coding in C# for a while, things get much easier to find the C# equivalents to VFP calls in many cases. Sometimes easier, sometimes a bit more effort but still doable.

How to properly create a property to store any amount of values?

Making the shift from C++ to C++/CX I stumbled upon that ref classes can't have native members in they're public or protected members, due to possible errors with java and stuff. Instead we now have to use properties, which I can make but only to hold 1 value...
The idea was to make a property that would store 4 floats in an array or vector and later pass the values to a XMVECTOR. The relevant code I have in the class header file until now is:
public:
property std::vector<float> num{
void set(std::vector<float> e){
NUM = e;
};
std::vector<float> get(){
return NUM;
};
};
private:
std::vector<float> NUM;
Later in the .cpp file I do:
std::vector<float> g;
g.pushback(3);
num = g;
I also make it a string to pass to a TextBox(but that's not important). In the end I just get many similar errors... The 2 errors are:
error C3986: 'set': signature of public member contains native type 'std::vector<_Ty>'
error C3986: 'set': signature of public member contains native type 'std::allocator<_Ty>'
The only thing I imagine is that I can't use strings or vectors. I know Platform::Strings exist but what about vectors??
Standard C++ types cannot be projected across the WinRT ABI, which is the communication layer shared by all WinRT language projections (C#/VB/JS). As Jagannath mentions, there is a collection interface (Windows::Foundation::Collections::IVector<T>). There is also a dictionary type (IMap<K,V>) and various iterators and support types. These are understood by all languages, but are just interfaces. Each language projection is responsible for authoring runtime classes that implement these interfaces. For C++/Cx, these ref classes are found in the header <collection.h> and are in the namespace Platform::Collections. Platform::Collections::Vector<T> and Platform::Collections::Map<K,V> are the basic types you can use as backing stores. Additionally, Vector<T> can be move-constructed from std::vector<T>.
However, you can't make a public property of type Platform::Collections::Vector<T> either, as this is still a C++ type. What you do instead is create a public property of type Windows::Foundation::Collection::IVector<T> which is backed by a private member variable of type Platform::Collections::Vector<T>.
Essentially:
public:
property Windows::Foundation::Collections::IVector<float>^ num{
Windows::Foundation::Collections::IVector<float>^ get(){
return NUM;
}
}
private:
Platform::Collections::Vector<float>^ NUM;
I have avoided mentioning the property setter, because that gets tricky (your private type would need to also be an IVector and it will only be a Platform::Collections::Vector if it came from C++).
You could use Windows::Foundation::Collections::IVector<float>^ for the signatures. I could not test this as I don't have the compiler at hand.
Hey guys I managed to get this working so I thought I'll post the code. The header file goes like this:
public:
property Windows::Foundation::Collections::IVector<int>^ num{
void set(Windows::Foundation::Collections::IVector<int>^ e){
NUM = safe_cast<Platform::Collections::Vector<int>^>(e);
};
Windows::Foundation::Collections::IVector<int>^ get(){
return NUM;
};
};
private:
Platform::Collections::Vector<int>^ NUM;
And in the .cpp file the code is:
num = ref new Vector<int>;
num->Append(5);
num->Append(54);
TextBox1->Text = num->GetAt(0).ToString() + "\n" + num->GetAt(1).ToString();
The result will have written the values 5 and 54 to a TextBox.

Faking enums in Entity Framework 4.0

There are a lot of workarounds for the missing support of enumerations in the Entity Framework 4.0. From all of them I like this one at most:
http://blogs.msdn.com/b/alexj/archive/2009/06/05/tip-23-how-to-fake-enums-in-ef-4.aspx?PageIndex=2#comments
This workaround allows you to use enums in your LINQ queries which is what i exactly need. However, I have a problem with this workaround. I get for every complex type I'm using a new partial autogenerated class.Therefore the code does not compile any more because I already have a wrapper class with this name in the same namespace which converts betwen the backed integer in the database and the enum in my POCO classes. If I make my wrapper a partial class, the code still does not compile as it now contains two properties with the same name "Value". The only possibility is to remove the Value property by hand everytime I generate the POCO classes because the DB model changed (which during the development phase happens very often).
Do you know how to prevent a partial class to be generated out of complex property everytime the EF model changes?
Can you recommend me some other workarounds supporting enumerations in LINQ queries?
That workaround is based on the fact that you are writing your POCO classes yourselves = no autogeneration. If you want to use it with autogeneration you must heavily modify T4 template itself.
Other workaround is wrapping enum conversion to custom extension methods.
public static IQueryable<MyEntity> FilterByMyEnum(this IQueryable<MyEntity> query, MyEnum enumValue)
{
int val = (int)enumValue;
return query.Where(e => e.MyEnumValue == val);
}
You will then call just:
var data = context.MyEntitites.FilterByMyEnum(MyEnum.SomeValue).ToList();
I am using an approach based on the one described in your link without any modifications of the T4 templates. The contents of my partial wrapper classes are as follows:
public partial class PriorityWrapper
{
public Priority EnumValue
{
get
{
return (Priority)Value;
}
set
{
Value = (int)value;
}
}
public static implicit operator PriorityWrapper(Priority value)
{
return new PriorityWrapper { EnumValue = value };
}
public static implicit operator Priority(PriorityWrapper value)
{
if (value == null)
return Priority.High;
else
return value.EnumValue;
}
}
I've only changed that instead of a back store variable with enum value I am using the autogenerated int typed Value property. Consequently Value can be an auto-implemented property and EnumValue property needs to do the conversion in getter and setter methods.

C# public partial struct methods for more System.Windows.Media.Color

How can I put in additional methods for manipulating color ?
Best would be to overload the struct System.Windows.Media.Color.
It is NOT a class (in c#).
Now i'm tinkering with putting (in the same file for testing or must i put it in a
different file) an namespace (Silverlight Application36 or System.Windows.Media ?)
and a partial struct Color Normalize (double R, ...).
I should see MyColor.Normalize() start being recognized by intellisense ?
I'm not. I'm looking to put in a suite of overloaded color manipulations using
floating and double numbers instead of unsigned byte integers.
Any hints while I wack at it ?
Cheers!
dr.K
Just use extension methods:
public static class ColorExtensions
{
public static Color Normalize(this Color)
{
return ...;
}
}
It's fine if its a struct.
I created a sample windows forms app and put in a .cs file:
namespace System.Windows.Media
{
public partial struct Color
{
public double Normalize(double r, double g, double b)
{
return r + g + b;
}
}
}
this causes the intellisense to show the Normalize method:

Resources