Cannot use pictureBox.Image in my class - c#

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.

Related

GetComponent(Type customType) behaving differently than GetComponent<customType>

I have this method 'SetStats' that's part of a class.
public class HeroUnit: MonoBehaviour {
public virtual void SetStats(Stats stats) => Stats = stats;
}
When I instantiate a gameObject by pointing to a prefab, then get the component of a known type 'HeroUnit' attached to it, I can call the SetStats method without any problem.
void SpawnUnit(Vector3 pos) {
var spawnedGameObject = Instantiate(unitPrefab, pos, Quaternion.identity,transform) as GameObject;
var spawned = spawnedGameObject.GetComponent<HeroUnit>();
spawned.SetStats(stats);
}
However, when I don't force a known component type, and that I rather give it dynamically to the GetComponent() method: the instantiation works, but I can't call the SetStats method anymore.
void SpawnUnit(String myUnit, Vector3 pos) {
var spawnedGameObject = Instantiate(unitPrefab, pos, Quaternion.identity,transform) as GameObject;
Type unitType = Type.GetType(myUnit);
var spawned = spawnedGameObject.GetComponent(unitType);
spawned.SetStats(stats);
}
This returns the following compile error :
error CS1061: 'Component' does not contain a definition for 'SetStats' and no accessible extension method 'SetStats' accepting a first argument of type 'Component' could be found
Any idea how to make the compiler understand that 'spawned' is not a 'Component' when the code is ran? I checked 'spawned' type at runtime, and it is a 'HeroUnit', as it should.
Take the var off and see if it'll compile. I don't think you're getting a HeroUnit, I think you're getting a Component.
Try casting the result of GetComponent, like
HeroUnit spawned = (HeroUnit) spawnedGameObject.GetComponent(unitType);
I'll say too that passing types around as strings is a bad idea. You got the string from somewhere, so just use the types instead of strings.
You're probably going to come back and complain about that your unitType isn't necessarily a HeroUnit, to which I would reply, "then how do you know it has a SetStats method?"
You might be better off casting to a base class or interface, but again this string business is not helping you.

how can i activate function update

the problem i have are
Assets\Scripts\Gunfire.cs(1,1): error CS0246: The type or namespace
name 'function' could not be found (are you missing a using directive
or an assembly reference?)
Assets\Scripts\Gunfire.cs(1,10): error CS0116: A namespace cannot
directly contain members such as fields or methods
the script is
function Update
{
get
{
if (Input.GetButtonDown("Fire1"))
{
var;
{ gunsound; }
AudioSource = GetComponent.AudioSource();
gunsound.Play();
GetComponent.Animation > (Play("GunShot"));
}
}
}
thank you very much
function is not a C# keyword. It looks like youa re trying to write JavaScript maybe.
C# function syntax is like this:
{returnType} {methodName} ({parameters}) { {body} }
int Add (int x, int y) { return x + y; }
In C# all functions must belong to a class. (This may change in C#9)
You can see an example of this if you create a new C# console app in Visual Studio.

Could not use Delegate's Method Property in 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.

How to reference Microsoft.Boogie when compiling with Mono?

using System;
using System.Collections.Generic;
using Microsoft.Boogie;
public class Trace
{
public static void Main(string[] args)
{
if (args.Length != 2){
return;
}
Program program = new Program();
List<string> defines = new List<string>();
Parser.Parse(args[0], defines, out program);
string[] lines = System.IO.File.ReadAllLines(args[1]);
Dictionary< Block, List<Block> > adj = new Dictionary< Block, List<Block> >();
foreach (Declaration D in program.TopLevelDeclarations){
Implementation I = D as Implementation;
if(I != null){
foreach (Block B in I.Blocks){
object cmd = B.TransferCmd;
if(cmd is GotoCmd){
List<Block> target = cmd.labelTargets;
adj.insert(B, target);
}
else if(cmd is ReturnCmd){
adj.insert(B, null);
}
}
}
}
}
}
I am new to C# and I am stuck on how to iterate over program.TopLevelDeclarations.
Trying to iterate over a simple list works but when I try to include the Microsoft Boogie library, the compiler throws a few errors.
I am compiling my program using gmcs on Ubuntu 13.04 using the command:
gmcs -r:../../boogie/Binaries/Boogie.exe -r:../../boogie/Binaries/Core.dll Trace.cs
Which gives the following errors:
Missing method .ctor in assembly /home/boogie/Binaries/Core.dll, type System.Diagnostics.Contracts.ContractClassAttribute
Can`t find custom attr constructor image: /home/boogie/Binaries/Core.dll mtoken: 0x0a000463
Trace.cs(19,52): error CS0584: Internal compiler error: Could not load type System.Diagnostics.Contracts.ContractClassAttribute from assembly Core.
Trace.cs(19,36): error CS0266: Cannot implicitly convert type object to System.Collections.Generic.List<Microsoft.Boogie.Declaration>. An explicit conversion exists (are you missing a cast?)
Trace.cs(22,30): error CS0584: Internal compiler error: Could not import type Microsoft.Boogie.Implementation from Core, Version=2.2.30705.1126, Culture=neutral, PublicKeyToken=736440c9b414ea16
Trace.cs(22,30): error CS0266: Cannot implicitly convert type object to bool. An explicit conversion exists (are you missing a cast?)
Trace.cs(23,55): error CS0584: Internal compiler error: Could not import type Microsoft.Boogie.Implementation from Core, Version=2.2.30705.1126, Culture=neutral, PublicKeyToken=736440c9b414ea16
Trace.cs(23,33): error CS1579: foreach statement cannot operate on variables of type object because it does not contain a definition for GetEnumerator or is inaccessible
Compilation failed: 6 error(s), 0 warnings
Does anyone know how to fix this? Am I including the libraries incorrectly?
I can't seem to find the source of Microsoft.Boogie.Declaration, but given the error messages it has a [ContractClass] attribute, which the compiler cannot find:
Trace.cs(19,52): error CS0584: Internal compiler error: Could not load type 'System.Diagnostics.Contracts.ContractClassAttribute' from assembly 'Core'.
Because of this the type Microsoft.Boogie.Declaration cannot be loaded, causing the List<Declaration> of program.TopLevelDeclarations to apparently be "stubbed" of some sort as an object. This in turn causes your code to fail, because you can't iterate over an object.
The ContractClassAttribute was added to mscorlib in .NET 4. You're using gmcs, which according to mono's CSharp Compiler manual page compiles against .NET 2.0.
I think you better compile using mcs, which is recommended there.

Invoking Method on Object Instantiated From DLL

I am having some trouble with assemblies and DLL's.
instrument_ is declared as an object and I'm creating an instance of "PP150" from the dll whose path is specified by path_.
string className = ContineoProperties.getSingleton().getClassName(path_);
assembly_ = Assembly.LoadFrom(path_);
Type classType = assembly_.GetType("Instrument." + className);
instrument_ = Activator.CreateInstance(classType);
Later I to call the method isntrument_.instrumentCommand(cmd.getCommandName())
The error I get is with when i call the method.
'object' does not contain a definition for 'instrumentCommand'
The isntrument_ is created fine. its just the method call that's giving me a problem. The method does exist in the "PP150.dll". Do I need some DLLImport to allow it to recognize it as a function?
Thanks,
P
If object type is not known in compile time,
To call a method defined on an object, you must use Reflection.
MethodInfo mInfo = classType.GetMethod("instrumentCommand");
mInfo.Invoke(instrument_, new Object[] { _parameters});
The compiler is never going to recognize the methods on a type that you are loading via reflection (e.g. using Assembly.GetType() and Activator.CreateInstance()). Unless you have the type metadata available at build time, you will always get that error if you try to call methods that are not defined on Object itself.
You have two options for making that kind of method call. Both of them require you to give up type safety, the only difference is the amount of work required. In both cases, if you make a mistake, the compiler will not tell you -- you will get a runtime exception instead.
Declare instrument_ as dynamic instead of object. This, obviously, only works in .NET 4.0, but it accomplishes exactly what you're trying to do. The method call will be dispatched at runtime, so as long as the instance that instrument_ references actually has a method call with the appropriate name, it will work.
Use reflection to call the method. You're already using reflection to load the type, so you are halfway there. You would need to add something like this:
// The array of types is the parameter list; assuming instrumentCommand takes
// a string it would look like this:
MethodInfo method = classType.GetMethod("instrumentCommand", new Type[] { typeof(string) });
method.Invoke(instrument_, new object[] { cmd.getCommandName() });
This happens because Activator.CreateInstance returns an object. I would create a separate DLL for the interface which is implemented by the class you want to instantiate. Both the DLL containing this class, and the executable should reference the DLL containing the interface. This way you could cast the object returned by Activator.CreateInstance to the interface, and call its methods:
IInstrument.dll:
interface IInstrument
{
void instrumentCommand(string cmd);
}
Instrument.dll (add IInstrument.dll as reference):
class Instrument : IInstrument
{
public void instrumentCommand(string cmd)
{
// ... implementation ...
}
}
InstrumentApp.exe (add IInstrument.dll as reference):
class Program
{
public static void Main()
{
// ... load Instrument.dll into assembly object ...
// ... load the type from the assembly ...
IInstrument instrument_ = (IInstrument)Activator.CreateInstance(classType);
instrument_.instrumentCommand(cmd.getCommandName());
}
}
The most simple thing would be to link agains PP150.
If you did link against the dll you must use Assembly.LoadFile or Assembly.Load and not LoadFrom because the last one will cause the assembly load to load your assembly in the LoadFrom loader context which will alter type identity.
Suppose you load the Type T from Assembly A via LoadFrom and you link against A as well.
object CreateTypeFrom()
{
var A = Assembly.LoadFrom(#"xxxx");
return A.CreateInstance("T");
}
void Test()
{
object t = CreateTypeFrom();
T RealT = new T(); // no prob
T Castedt = (T)t; // this will throw an InvalidCastException
T isNull = t as T; // this will result in a null instance
}
As you can see although you did create two times an instance of T they cannot be casted to due to different loader context which will make the type pretty useless.
To get rid of these things you could simply use Reflection to create a proxy type which will forward your calls to the proxy type. If you are using .NET 4 you can take advantage of the DLR to find the best matching methods at runtime. The code below creats a Version object and returns it as dynamic object. Then I do call the Major property to an integer and print it out to console. This does work with no exceptions nor compile time errors if you are using .NET 4 or later.
dynamic CreateTypeFrom()
{
var assembly = typeof(string).Assembly;
return assembly.CreateInstance("System.Version", true, BindingFlags.CreateInstance, null, new object[] { 1, 2, 3, 4 }, null, null);
}
[TestMethod]
public void Test()
{
var t = CreateTypeFrom();
int major = t.Major;
Console.WriteLine(major);
}

Categories