In my application, different canvases are stored as "pages", the contents of each canvas is stored as "cells".
Now when I want to load all cells that occupy / make up one canvas, I retrieve them like this:
public Task<List<Cell>> GetCellsAsync(string uPageGUID)
{
return database.QueryAsync<Cell>("SELECT * FROM cells WHERE cellpageguid = ?", uPageGUID);
}
This works great.
Now I would like to find out the "pageguid" of the page that has the value "pageisstartpage" set to true.
Therefore I'm trying the following:
public Task<string>GetStartPageGUID()
{
nPages<List<Page>>=database.QueryAsync<Page>("SELECT * FROM pages WHERE pageisstartpage=?", true);
return nPages.First.GUID;
}
The compiler tells me:
nPages doesn't exist in the current context.
I don't see where I made a mistake.
nPages doesn't exist in the current context....I don't see where I made a mistake.
The first thing to mention is that the declaration of the List<Page> seems backwards.
nPages<List<Page>>=database....
The type has to be written first followed by the variable name.
List<Page> nPagesTask = database...
Another interpretation could be that you have a generic type variable nPages in which you want to specify the generic type. So the compiler looks whether this variable has already been declared. And apparently it cannot find any.
The second thing If you have an async method that returns a Task<string> you could do the following:
public async Task<string>GetStartPageGUID()
{
Task<List<Page>> nPagesTask = database.QueryAsync<Page>("SELECT * FROM pages WHERE pageisstartpage=?", true);
List<Page> npages = await nPagesTask;
return nPages.First().GUID;
}
Here is the source of the QueryAsync method. this is the signature:
public Task<List<T>> QueryAsync<T> (string query, params object[] args)
so it returns a Task<List<T>>. Since your method specifies a different return type the usual pattern is to await it in a async method as described in the MSDN example and then return the type that you specified in you method.
You have to declare nPages correctly:
List<Page> nPages = database.QueryAsync<Page>("SELECT * FROM pages WHERE pageisstartpage=?", true);
Related
I have the following code:
static int rnd_nmb()
{
Random rnda = new Random();
int skw1 = rnda.Next(1, 11);
return skw1;
}
private void function1()
{
rnd_nmb1();
MessageBox.Show(Convert.ToString(skw1));
}
I want to reuse the variable skw1 to show it on a Message Box, but it says:
"the name 'skw1' does not exist in the current context.".
I don't know what the problem is. Btw. it's a Windows Forms App and i'm using Visual Studio 2019.
I added the 'return' statement and thought it would work, but it doesn't.
there is no need to reuse the local variable, since you wrote a method named rnd_nmb which returns your desired value. Catch the returned value and use it:
private void function1()
{
int returnValue = rnd_nmb();
MessageBox.Show(returnValue.ToString);
}
I don't know what the problem is
One problem is the scope. The variable skw1 exists only withing the scope of the method in which it is declared. The scope is limited by { and }
Second problem is that you need to use the correct names when you try to call a method. You declared rnd_nmb but then you try to use rnd_nmb1
Third hint is that methods with a return value are exactly designed for the user to not care what happens inside of them. You use them and catch the result. It is like a toaster, you put bread in it and you catch the toasted stuff that come out in the end. You don't try to pull out the heating coil and use it on the bread, .... hopefully not... ;)
[INTRO]
I know there are about a zillion QA about generics and reflections everywhere, but it's becoming a blackhole to me, and I'm only getting more lost the more I read!!
What i need to do is simple, and I'm amazed that it hasn't been addressed before.
[SAMPLE] Consider the following snippit:
public async Task<string> generateJsonSchema(string model)
{
try
{
string modelName = "Models." + model;
Type t = Type.GetType(modelName, false);
JsonSchema4 schema = await JsonSchema4.FromTypeAsync<t>();
return schema.ToJson();
}
catch (Exception ex)
{
Logger.WriteToLogFile(ex.ToString(), "exception");
return "";
}
}
[PROBLEM] Now the main problem is that variable t is evaluated at runtime, thus, JsonSchema4.FromTypeAsync<t>() throws the error 't' is a variable but is used like a type when trying to build compile time
Whoever used JsonSchema4 will understand what I'm trying to achieve here.
Instead of creating a generate function for each of my models, or make a switch/if-else logic,
[QUESTION]
How to make it receive the model name as a string parameter, and convert the string-model-name to model-type and pass it to jSonSchema4 method.
The problem here is that, as you say, t is evaluated as runtime.
I also ran into this Problem and solved it by creating a MethodInfo of the method I wanted to invoke, in your case JsonSchema4.FromTypeAsync<t>().
So basically this is want may fix the problem:
var methodInfo = typeof(JsonSchema4).GetMethod("FromTypeAsync", new Type[] { }); //Get the "normal method info", the overload without parameters
var methodInfoWithType = methodInfo.MakeGenericMethod(t); //now you have a method with your desired parameter t as TypeParameter
Task<JsonSchema4> task = methodInfoWithType.Invoke(null, null) as Task<JsonSchema4>; //now you can cast the result from invoke as Task to keep the Async-Await functionality
var schema = await task;
return schema.ToJson();
This is from the factory pattern, where a property is used to get an instance via Create:
public class Dialer
{
public static Func<Dialer> Create;
public bool MakeCall(string number) ...
public Dialer(IDialer impl) { ... }
}
Then a lambda expression is assigned to the property delegate in the platform-specific project with
Dialer.Create = () => new Dialer(new PhoneDialeriOS());
and to get an instance in the platform-independent project I use
this.dialer = Dialer.Create();
Now I'm looking to use
public static Action<Dialer> Create;
If I get this right, the assignment now is
Dialer.Create = (d) => new Dialer(new PhoneDialeriOS());
but how do I get an instance?
this.dialer = // ?
By using this.dialer = Dialer.Create(); I get
Error CS7036 There is no argument given that corresponds to the required formal parameter 'obj' of 'Action'
But it doesn't make sense to pass an instance of PhoneDialeriOS here, because there is no access to it in the platform-independent code. I think the example I'm regarding to is misleading or I'm missing something.
Action<Dialer> is a a delegate that receives a Dialer instance, and returns void. It's an Action, after all. If you want it to return a value (and get an argument), you need to use Func<Dialer, Dialer> instead.
The following could be possible usages
var specific_dialer = new Dialer(new PhoneDialeriOS());
var defualt_dialer = Dialer.Create();
Edit
Of course you can do something like
Dialer.Create = () => new Dialer(new PhoneDialerAndroid());
without the (likely a wrong copy/paste) line with the Action
I am trying to create a new property that has the same body as a method.
Here is my code so far:
private async Task<Solution> ConvertMethodToProperty(Document document, MethodDeclarationSyntax methodNode, CancellationToken cancellationToken)
{
AccessorListSyntax accesors = SyntaxFactory.AccessorList(new SyntaxList<AccessorDeclarationSyntax>
{
SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration, methodNode.Body)
});
PropertyDeclarationSyntax newp = SyntaxFactory.PropertyDeclaration(new SyntaxList<AttributeListSyntax>(), methodNode.Modifiers, methodNode.ReturnType, methodNode.ExplicitInterfaceSpecifier, methodNode.Identifier, accesors);
SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
document = document.WithSyntaxRoot(root.ReplaceNode(methodNode, newp));
return document.Project.Solution;
}
}
However when I run this on my test project I see this:
Even though the methodNode.Body from the code is populated with the method body I want:
What am I doing wrong when I create my AccessorListSyntax? Thanks!
I think your use of the collection initialiser on the SyntaxList is not valid. As that will implicitly call the Add method on your SyntaxList but the add doesn't modify the underlying collection it just returns a new SyntaxList. Try instantiating and manually adding afterwards like this.
var accessorList = new SyntaxList<AccessorDeclarationSyntax>();
accessorList = accessorList.Add(SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration, methodNode.Body));
I fell into the same trap when I started playing around with Roslyn, just have to remember the immutability thing.
I have a method that returns Task< PixelData >.
myObject.pixelData = await rootPage.GrabPixelData("mypic.png");
I have confirmed (from the debugger) that the method completes (and returns a non-null value), but when execution returns myObject.pixelData remains null.
Stangely, the line immediately after that point is never hit (a breakpoint I set there never stops execution).
Here is the class:
public class PixelData
{
public byte[] sourcePixels;
public int sizeOfSourcePixels;
public int imageWidth;
public int imageHeight;
}
Here is the method that gets called:
public async Task<PixelData> GrabPixelData(string imageFileName)
{
if (!ImageDictionary.ContainsKey(imageFileName))
{
// doesn't exist yet, so load it
PixelData pd = await LoadPic(imageFileName);
ImageDictionary.Add(imageFileName, pd);
}
var test = ImageDictionary[imageFileName];
return ImageDictionary[imageFileName];
}
I'm pretty new to async / await, and I can't seem to figure this one out.
Do I need to inherit from a certain interface in the PixelData class? Do I need to cast the result to another type? Why doesn't the very next line ever get executed?
I strongly suspect the cause is some hidden, arcane aspect of .NET 4.5 or it's a bug.
Anyway, the workaround for me was to make an asynchronous call to load the file into the parent class and then grab it in the next line.
Something like this:
await rootPage.LoadPixelData("mypic.png");
myobject.pixelData = rootPage.ImageDictionary["mypic.png"];
loadedFlag = true;
Is my layout of the classes a little strongly typed? Yes. That's because XAML wipes out my class every time I switch pages, so I have to store everything in the parent class to avoid reloading.