I want to create something for my .NET project.
I write it in C++ Cli because this is something that I can't do in C#.
I need to create a class that extends System::IO::TextWriter.
When I try to override the methods with the async identifier I get an error.
Because in C++ there is no keyword like C# async keyword that I could find, I have no way to override it as an async method.
How do I do that?
async is an implementation detail, not part of the method signature.
Make sure the return type (derived from Task<>) matches, and the override will be accepted. You can use a TaskCompletionSource or Task.FromResult to create the returned task.
Related
Is there any thumbrule for a beginner to understand when to use which life cycle methods, when developing a Blazor Server app.
OnInitialized() vs OnInitializedAsync()
OnParametersSet() vs OnParametersSetAsync()
OnAfterRender() vs OnAfterRenderAsync()
OnInitialized() vs OnInitializedAsync()
Prefer the simple OnInitialized() to set data without async, like message="hello";.
As soon as you have to call and await async methods, for instance on HttpClient, switch to OnInitializedAsync().
More rules of thumb:
do not use .Result or .Wait() on async methods
do not start async methods without awaiting them
do not use async void except in very rare cases.
When you get it wrong there will be an Error (can't await) or a Warning:
CS4032 The 'await' operator can only be used within an async method.
Is obvious, you should have used a *Async method. But do not 'fix' it by using async void or .Result.
CS1998 This async method lacks 'await' operators and will ...
means you should not have used the *Async method.
CS4014 Because this call is not awaited, ...
means you are not awaiting something you should.
Here's the code that I have:
public App()
{
InitializeComponent();
DB.CreateTables();
DB.GetSettings();
DB.PopulateTables();
SetResourceColors();
SetResourceDimensions();
MainPage = new MainPage();
activity = Helpers.Activity.Create();
VersionTracking.Track();
DeviceDisplay.MainDisplayInfoChanged += OnMainDisplayInfoChanged;
}
protected override void OnStart()
{
}
Can someone explain to me. Is there any difference between me placing the code such as I have in the constructor or in the OnStart() method? What's the normal way to do this?
I have been working with Xamarin.Forms for a long time now and this is how I and my fellow developers use the OnStart Method.
If you check the Microsoft documents it says the following about it :
OnStart - Called when the application starts.
So, first of all, you should know that there is no specific use of the OnStart method, to be very honest there is no major difference in between using the constructor or this lifecycle method because both get called on XF framework startup, first the constructor then the OnStart method.
Now let's come to the differences.
As Jason pointed out, the OnStart method is a lifecycle method and hence has a return type unlike the constructor, so you can even call an asynchronous piece of code in the OnStart method but you cannot do the same in the constructor as constructors cannot be asynchronous.
Which means if you have the below method:
public async Task<bool> IsSomeThingWorkingAsync(//SomeParams)
{
// Code
}
Now, this method cannot be asynchronously called from the constructor since constructors are forcefully synchronous and have no return types. But if you try doing that from the on start method it's quite easy and it will work. In this case, you use the OnStart method. Something like below:
protected override async void OnStart()
{
bool WasWorkSuccess=await IsSomeThingWorkingAsync();
//do something with the boolean
}
A constructor is intended to be used for wiring. In the constructor, you want to avoid doing actual work. You basically prepare the class to be used. Methods are intended to do actual work.
Note: There are no performance gains whatsoever by choosing one over the other - it's really a matter of preference and standard.
Please go through the details here
You can write the initialisation codes in App() constructor. But you need to be very careful abut registering events.
Reason is,
For example in Android, If the app is launched and it is in task list and if you try to launch the app again by clicking on app icon. The constructor of App() will call again. This will register the event multiple times and will create issues.
So for events I will suggest you to use overriden methods for registering events.
Again as Jason pointed it out, It is your personal preference where to write your code.
Is there any way I can make sure I can take advantage of override keyword without writing override after each method.
I have couple of points to desire such a thing
Its error prone to mark each method override when you are dealing with legacy code and introducing the override keyword in the existing class
You have too many override methods
Override methods maybe scattered around in class declaration mangled with bunch of other methods
I am looking for something like override block using scope, when any method is part of this block its same as writing override after the method signature.
I am pretty sure there is no such thing as override block in standard but can we implemnt something using macro or other stuff?
e.g.
class derived
{
public:
override {
int blah();
void blahBlah();
.. so on
};
};
Is there any way I can make sure I can take advantage of override keyword without writing override after each method.
I'm afraid not. There's nothing in the Standard regarding override blocks or anything similar.
If you feel like this should be added to the language, write a proposal.
I have a Sitecore project in which I am using visualstudio code analysis. I am using Sitecore method "Assert.ArgumentNotNull" to check for null arguments, However visualstudio code analysis engine doesn't recognize it and show "CA1062 Validate arguments of public methods" message.
Instead of creating a custom rule, Is there a easier way to tell analysis engine that "Assert.ArgumentNotNull" performs null check and message is invalid.
I don't want to suppress the message or disable it.
You can't use Sitecore's Assert class that way and that's why:
Sitecore Assert class as well as NotNullAttribute and CanBeNullAttribute were made the way ReSharper can understand when it performs its own analysis.
Definition of Assert.ArgumentNotNull(object, string) method is the following:
[AssertionMethod]
public static void ArgumentNotNull([CanBeNull] [AssertionCondition(AssertionConditionType.IS_NOT_NULL)] object argument, [CanBeNull] [InvokerParameterName] string argumentName)
All those attributes are defined in Sitecore and R# understands them because of naming conventions.
Unfortunately, VS code analysis has another naming conventions. ArgumentNotNull should look like this for you:
public static void ArgumentNotNull([ValidatedNotNull] object argument, string argumentName)
Since you can't modify the Assert class, you can't mark argument parameter with ValidatedNotNullAttribute.
I would like to handle a button clicked event in a native c++ class. I have tried creating a 'handler' object derived from Object to handle the event and then calling a c++ method. For example I tried the following code:
ref class GButtonHandler sealed : public Object
{
public:
void Button_Click(Object^ sender, RoutedEventArgs^ e)
{
}
GTextBlockHandler(GButtonImpl * pButtonImpl, Button ^ button)
{
button->Click += ref new RoutedEventHandler(this, >extBlockHandler::Button_Click);
}
};
Thinking that I could squirrel away the pButtonImpl pointer and then use it to call a native function in the Button_Clicked function. However on compiling this code, I get the error:
error C3986: '{ctor}': signature of public member contains native type 'GButtonImpl'
So it seems that it does not like me passing in native classes into an ref object. Is there a way to do this?
Note that I am completely new to developing Metro style apps, so bear with me!
Ok, it all makes sense to me now. For anyone else who is interested, the reason you cannot have WinRT Objects with public functions that have native C++ arguments is that these objects would then not be consumable by non C++ code. However, the (obvious?) solution is to make the constructor private and have the class that creates the Object declared as a 'friend' class (duh!). Then all is well, the compiler is happy, and I am happy.
Thanks to all who took the time to read this.
The correct answer is to use internal rather than public for the constructor. This tells the compiler that it will only be available in the current project, and won't be available to external projects (i.e. a library written in another language).