Could not use Delegate's Method Property in C#? - c#

When i try to use Delegate's Method Property in C# i get this error.
'myDelegate' does not contain a definition for 'Method' and no
extension method 'Method' accepting a first argument of type
'myDelegate' could be found (are you missing a using directive or an
assembly reference?)
I really don't know the reason why i get this. My program is fairly simple and is based on delegates. Below it's code is given:
public delegate void myDelegate(int x);
public class Program
{
public void Main(string[] args)
{
X x = new X();
myDelegate d = x.InstanceProgress;
Console.WriteLine(d.Method);
}
}
class X
{
public void InstanceProgress(int percent) => Console.WriteLine(percent);
}
I get error on this line:
Console.WriteLine(d.Method);
See this image below, although i get the proper output but i get the error.
I have marked the error with green arrow on the image.

Looking at OP's screenshot. That looks like a Visual Studio error. And since it lets you build the it's not a true error. I don't get that error in VS2015.
I'd clean the solution and restart visual studio. That should clear it.
Old:
You'll want to do something like this:
X x = new X();
myDeligate d = x.InstanceProgress;
d.Invoke(5);
// or as Rahul pointed out you can simply use
d(5);
Invoke() is what actually calls the method. Until then the delegate is just a pointer to the method that you want to call.

Related

Can anyone help me with the loadingSceneIndex issue

does anyone know where the error is? I've been looking for various solutions but I didn't get what I wanted
public static void LoadScene(int levelNum)
{
Application.backgroundLoadingPriority = ThreadPriority.High;
sceneToLoad = levelNum;
SceneManager.LoadScene(loadingSceneIndex);
}
Eror : Assets\Script AR\LoadingScreenManager.cs(35,32): error CS0103: The name 'loadingSceneIndex' does not exist in the current context
and one more problem this one
private void StartOperation(int levelNum)
{
Application.backgroundLoadingPriority = loadThreadPriority;
operation = SceneManager.LoadSceneAsync(levelNum, loadSceneMode);
if (loadSceneMode = LoadSceneMode.Single)
operation.allowSceneActivation = false;
}
Eror : Assets\Script AR\LoadingScreenManager.cs(91,13): error CS0029: Cannot implicitly convert type 'UnityEngine.SceneManagement.LoadSceneMode' to 'bool'
The first error happens because the variable loadingSceneIndex doesn't exist. You should plug the scene you want to load into the LoadScene function like this:
SceneManager.LoadScene(levelNum);
That way the LoadScene function knows which scene to load.
The second error happens because in you're if statement expects a bool, but plug in loadSceneMode = LoadSceneMode.Single. That is defining loadSceneMode. Instead, use loadSceneMode == LoadSceneMode.Single instead because that will return a bool.
Note: Have you looked into using something like Intellisense so your editor can detect these errors for you. If you are using Visual Studio, this link might help.

Console.WriteLine() error CS1503 cannot convert from 'void' to 'bool'

I am executing this simple program in which I am trying to see the outcome of Console.WriteLine with function returning void given as an argument.
using System;
class Program
{
static void printMe()
{
}
static void Main(string[] args)
{
Console.WriteLine(printMe());
}
}
This is giving following error:
Program.cs(11,27): error CS1503: Argument 1: cannot convert from 'void' to 'bool' [C:\Users\Nafeez Quraishi\source\repos\X\X.csproj]
The build failed. Fix the build errors and run again.
As per the WriteLine documentation at https://learn.microsoft.com/en-us/dotnet/api/system.console.writeline?view=netframework-4.8
this looks to be corresponding to following case:
WriteLine(Object)
Writes the text representation of the specified object, followed by
the current line terminator, to the standard output stream.
Question is:
In order to write text representation of the function object returning void, why is it trying to covert it in to bool(than perhaps string)?
the void is treated specially by C# language and .net runtime. so a user can not create an instance of void by static way or dynamic way.
Now come to your question about why it converts into bool and not in the string.
if you run below code in unsafe assembly. you can see it has size of 1 byte.
this lead to convert into bool and not string
static unsafe void Main(string[] args)
{
//Console.WriteLine(sizeof(System.Void));
var o = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(void));
Console.WriteLine(System.Runtime.InteropServices.Marshal.SizeOf(o));
Console.Read();
//Console.WriteLine(System.Runtime.InteropServices.Marshal.SizeOf(System.Void));
}
How do you print one void (obviously means 'void'-nothing, not even null)? You must return something, not 'void'
If you want, you can do
static bool!!!!! printMe() //Hi I'm a function returning a value, bool precisely.
{
return false; //I must return something.
}
Edit: you want the signature of the function/method?
You want Reflection. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection
static void Main()
{
MethodInfo[] mInfo= typeof(TheClass).GetMethods();
//now you can enumerate the methods, and know everything about them, even run them
}
Welcome to new way to use C#, there are so many space, get in.

Use Action instead of Func

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

Cannot use pictureBox.Image in my class

I am making a game and I have a class called gameScripts. Inside gameScripts is a public void method called paintSquare. When this method is called,the method uses 2 if statements,and depending on which one is true,the squares image will be changed accordingly.
The problem is,when I try to use pictureBox.Image = Image.FromFile("cross.png"); to change the picture to a cross,pictureBox.Image gets a red line under it with the error message "Error 2 'System.Windows.Forms.Control' does not contain a definition for 'Image' and no extension method 'Image' accepting a first argument of type 'System.Windows.Forms.Control' could be found (are you missing a using directive or an assembly reference?) c:\x\x\x\x\x\x\x\gameScripts.cs"
I have tried including System.Drawing and System.Windows.Forms in my namespaces,but I still get this error.
Any help would be appreciated,thanks.
The message 'ClassXXX' does not contain a definition for 'YYY' and no extension method 'YYY' accepting a first argument of type 'ClassXXX' could be found (are you missing a using directive or an assembly reference?) means literally what it says. Most likely in you code there is construction like this:
myObject.YYY
but the class, the instance of which the myObject is, does not have a member with name YYY.
For example:
class MyClass {
public string MyField;
}
...
var myObj = new MyClass();
myObj.MyField = "OK";
myObj.NotMyField = "FAIL"; // compiler will complain at this line
However, the compiler gets the list of available properties and methods by looking at the variable type. This may lead to the situation when the object itself have the member but compiler cannot see it as the variable is defined with a different type.
Consider the following code fragment:
class MyExtClass : MyClass {
public string MyNewField;
}
...
MyClass myObj = new MyExtClass();
myObj.MyField = "OK";
myObj.MyNewField = "FAIL"; // compiler will complain at this line
// because MyClass does not have it
So in your code the pictureBox is seems to be defined as System.Windows.Forms.Control. So even if it is, in fact, System.Windows.Forms.PictureBox, compiler cannot know it and stops with the error.

Why are "DisplayClass" and calling method name ordered this way in the stack trace?

First of all, I've read this answer and no, it only says how it is implemented right now, but doesn't explain why.
Here's a sample program (same as here):
class Program
{
static void Main()
{
try {
implMain();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
static void implMain()
{
for (int i = 0; i < 10; i++) {
invoke(() => {
Console.WriteLine(i);
throw new InvalidOperationException();
});
}
}
static void invoke(Action what)
{
what();
}
}
which outputs the following call stack:
System.InvalidOperationException
at ConsoleApplication1.Program.<>c__DisplayClass2.<implMain>b__0()
at ConsoleApplication1.Program.invoke(Action what)
at ConsoleApplication1.Program.implMain()
at ConsoleApplication1.Program.Main()
Note these two lines:
at ConsoleApplication1.Program.<>c__DisplayClass2.<implMain>b__0()
at ConsoleApplication1.Program.invoke(Action what)
The lower one (with invoke()) says that there's namespace ConsoleApplication1 with class Program in it that has member invoke(). Here left-to-right corresponds to outer-to-inner.
The upper one (with c__DisplayClass2) says again there's a namespace and a class...
and then there's c__DisplayClass2 which means "a magic name the compiler chosen for storing captured variables" and then there's <implMain> as if it is a parameter to c__DisplayClass2. So it reads as if c__DisplayClass2 somehow is part of Program and implMain is part of c__DisplayClass2.
Now as I see it it's logically the opposite - there's implMain() method and there's "magic class" c__DisplayClass2 crafted specifically for implMain() local variables. So to me it looks like the upper line should look like this:
at ConsoleApplication1.Program.implMain.c__DisplayClass2.b__0()
(maybe with some extra symbols to prevent possible conflicts) but I hope my idea is clear - this way it would look like c__DisplayClass2 is crafted specifically to facilitate implMain() functioning.
Is there any reason why the current implementation shows the method name (implMain) after the local variables capture class name (c__DisplayClass2) and not vice versa?
<implMain>b__0() is just the name of the method.
Inspection in a disassembler will show you this. The < and > does not imply generics.
The inclusion of implMain probably just hints where the delegate was created.

Categories