Object of type 'MyClass' cannot be converted to type 'System.Object[]' C# - unity3d

I've been looking into this for a couple of hours but so far haven't gotten any luck.
Here's my C# code:
myClassInstance = new MyClass("MyParam", 1);
object[] args = new object[1] { myClassInstance };
MethodInfo methodInfo = GetType().GetMethod(myMethod, BindingFlags.NonPublic | BindingFlags.Instance);
string method = (string)methodInfo.Invoke(this, args);
I have MethodInfo and System.Reflection imported. The Unity error is this:
ArgumentException: Object of type 'SystemController' cannot be converted to type 'System.Object[]'
It doesn't point to a specific line in the code, but from what I can tell it seems to be an issue with converting the myClassInstance variable to an object, which doesn't make sense to me, as I believed everything in C# inherited from System.Object.
Here is MyClass:
public class MyClass
{
public string var1;
public int var2;
public MyClass(string param1, int param2)
{
var1 = param1;
var2 = param2;
}
}
Clearly, I'm not showing the entire class, but the only difference is that there are more variables and parameters to store. Those shouldn't change anything, so I won't bore you with them. It's just a class with a constructor, not inheriting from anything.
Any help I could get with this would be greatly appreciated. Let me know if you need more info.

The error here was me trying to pass the entire object[] array into my method as a parameter when I should have only passed the contents of the array. See here:
I was doing this:
void MyMethod(object[] args) {
MyClass instance = (MyClass)args[0];
...
}
But should've done this:
void MyMethod(MyClass myClassInstance) {
...
}
After reading some more documentation and reviewing the comments above I discovered that the .Invoke() method passes what's inside the args array instead of the entire array. At least, that's my current understanding, and it's what made my code work.
Thanks for the help.

Related

va_arg prevents me from calling a managed delegate in a native callback

In a C++/CLI assembly, I'm trying to call a managed delegate from a native callback. I followed Doc Brown's answer here, and my implementation so far looks like this:
The native callback - ignore the commented out parts for now:
static ssize_t idaapi idb_callback(void* user_data, int notification_code, va_list va)
{
switch (notification_code)
{
case idb_event::byte_patched:
{
//ea_t address = va_arg(va, ea_t);
//uint32 old_value = va_arg(va, uint32);
return IdaEvents::BytePatched(0, 0);
}
break;
}
return 0;
}
As you can see above, I call this managed delegate instantiated in a static class:
public delegate int DatabaseBytePatchedHandler(int address, int originalValue);
private ref class IdaEvents
{
static IdaEvents()
{
BytePatched = gcnew DatabaseBytePatchedHandler(&OnDatabaseBytePatched);
}
public: static DatabaseBytePatchedHandler^ BytePatched;
private: static int OnDatabaseBytePatched(int address, int originalValue)
{
return 0;
}
};
This compiles fine. But the code is incomplete - remember the commented out part in the native callback above? I actually have to retrieve the values from the va_list passed to the callback, and pass those on to my managed delegate:
ea_t address = va_arg(va, ea_t);
uint32 old_value = va_arg(va, uint32);
return IdaEvents::BytePatched(address, old_value);
But as soon as I uncomment one of the lines using va_arg, I cannot compile the project anymore and retrieve the following errors marking the line where I call the managed delegate:
C3821 'IdaEvents': managed type or function cannot be used in an unmanaged function
C3821 'IdaEvents::BytePatched': managed type or function cannot be used in an unmanaged function
C3821 'BytePatched': managed type or function cannot be used in an unmanaged function
C3821 'DatabaseBytePatchedHandler::Invoke': managed type or function cannot be used in an unmanaged function
C3642 'int DatabaseBytePatchedHandler::Invoke(int,int)': cannot call a function with __clrcall calling convention from native code
C3175 'DatabaseBytePatchedHandler::Invoke': cannot call a method of a managed type from unmanaged function 'idb_callback'
This really confuses me. Why is the compiler suddenly acting up as soon as I try to use va_arg? Even a single line without any assignment causes this error to pop up.
Am I thinking too naive here? I'm obviously missing a piece of the puzzle, and any help supporting me in finding it is greatly appreciated.

Class in parameter of function (Arduino) does not compile

I am trying to create a simple class in C++, but I keep getting the compilation errors:
main:2: error: variable or field 'doSomething' declared void
main:2: error: 'person' was not declared in this scope
main:
class person {
public:
int a;
};
void doSomething(person joe) {
return;
}
main() and stuff would go here, but even if I include main(){}, the errors still occur. I also tried adding 2 closed parentheses after joe, but then that creates the error:
main: In function 'void doSomething(person (*)())':
main:8: error: request for member 'a' in 'joe', which is of non-class type 'person (*)()'
Any help is greatly appreciated. (I hope this isn't something really stupid I'm missing, because I've been researching for hours).
Edit: I found out this is an Arduino-specific error. This post answers it.
I found out after reading this post that a way to work around this is:
typedef struct person{
public:
int a;
};
void doSomething(void *ptr)
{
person *x;
joe = (person *)ptr;
joe->a = 3; //To set a to 3
//Everything else is normal, except changing any value of person uses "->" rather than "."
return;
}
main()
{
person larry;
doSomething(&larry);
}
So essentially it is:
-Change class to typedef struct
-in the parameter, replace newtype with void *something
-add person *x; and x = (person *)ptr; to the beginning of the function
-whenever accessing type property, use -> rather than .
I'm not a expert but when I try to do what you want to do, I do it this way:
//create an instance of my class
MyAwesomeClass myObject;
void myFunction(MyAwesomeClass& object){
//do what you want here using "object"
object.doSomething();
object.doSomethingElse();
}
void setup() {
//setup stuff here
myObject.init();
}
void loop() {
//call myFunction this way
myFunction(myObject);
}
As I said, I'm not a C++ expert but it does the job.
Hope it helps!
My guess is, you have an invalid syntax error somewhere in the declarations above "class person...". Can you copy and paste the whole file?

Why do I get a lambda error that no-one else gets?

I'm trying to debug the following line:
MOrigValue.AllInstances.TestString = () => "New value";
There's a red squiggly line under:
() => "New value";
Mouseover shows the following error:
Delegate 'Microsoft.Moles.Framework.MolesDelegates.Func<OrigValueP.OrigValue, string>' does not take 0 arguments
Here is the complete class:
namespace OrigValueP
{
public class OrigValue
{
public string TestString() { return "Original value"; }
}
}
Here's the info from the object browser.
Click on the property MOrigValue.AllInstances.TestString:
public static Microsoft.Moles.Framework.MolesDelegates.Func<OrigValueP.OrigValue,string> TestString { set; }
Member of OrigValueP.Moles.MOrigValue.AllInstances
So, to a non-techie like me, that would explain the red squiggly line error above..
Click on the property MOrigValue..TestString:
public Microsoft.Moles.Framework.MolesDelegates.Func<string> TestString { set; }
Member of OrigValueP.Moles.MOrigValue
To me, this looks like the definition that I would have expected to see for MOrigValue.AllInstances.TestString. In other words a property that is actually a Moled "method" that has no parameters and returns a string.
As an experiment, based on the first object browser info above, I inserted the class as an input parameter, as follows:
MOrigValue.AllInstances.TestString = (OrigValue) => "New value";
This works :)
But my workaround looks like a "hack". I've seen every page on the internet (including StackOverflow) relating to moles and how to remove them painlessly. Many of them have lines with a lambda similar to the following:
MMyClass.AllInstances.DoSomething = () => "Hello world";
Assert.AreEqual("Hello world", new MyClass().DoSomething());
The fundamental issue is that Moles started from a method that takes no parameters and returns a string. The Moled equivalent takes its own class as a parameter and returns a string. Surely Moles knows that TestString() is a member of OrigValue.
Maybe my problem is a result of using VS Express, rather than the paid versions. I can live with that, but it would still be interesting to know why I need the hack. There might be cases where the hack produces incorrect test results without my knowledge.
BTW: I think this example proves the value of the object browser.
Your expectation is wrong. The "hack" you describe is the official documented way to use the AllInstances nested type. Its delegates really do always take a parameter containing an instance of the type under test.
It is unlikely that you could have seen this form of usage of AllInstances
MMyClass.AllInstances.DoSomething = () => "Hello world";
which, if you have, could be a mistake made by the author of the code.
What you expect to be the definition of a delegate belonging to the AllInstances type is really a different kind of use of Moles: it's used to detour an instance method of a single instance.
The "Mole Basics" section of the document "Microsoft Moles Reference Manual" contains more information on the topic. Here is an excerpt from there.
Instance Methods (for One Instance)
... The properties to set up those moles are instance methods of the mole type itself. Each instantiated mole type is also associated with a raw instance of a moled method type.
For example, given a class MyClass with an instance method MyMethod:
public class MyClass {
public int MyMethod() {
...
}
}
We can set up two mole types of MyMethod such that the first one always returns 5 and the second always returns 10:
var myClass1 = new MMyClass() { MyMethod = () => 5 };
var myClass2 = new MMyClass() { MyMethod = () => 10 };

C# - Why can I not cast a List<MyObject> to a class that inherits from List<MyObject>?

I've got an object, which I'll call MyObject. It's a class that controls a particular data row.
I've then got a collection class, called MyObjectCollection:
public class MyObjectCollection : List<MyObject> {}
Why can I not do the following:
List<MyObject> list = this.DoSomethingHere();
MyObjectCollection collection = (MyObjectCollection)list;
Thanks in advance.
Edit: The error is InvalidCastException
My guess is that DoSomethingHere doesn't return an instance of MyObjectCollection.
Let's get rid of all the generics etc here, as they're not relevant. Here's what I suspect you're trying to do:
public static object CreateAnObject()
{
return new object();
}
object o = CreateAnObject();
string s = (string) o;
That will fail (at execution time) and quite rightly so.
To bring it back to your code, unless DoSomethingHere actually returns a MyObjectCollection at execution time, the cast will fail.
Because a List<MyObject> is not a MyObjectCollection. The reverse is true: you could cast a MyObjectCollection to a List because MyObjectCollection inherits from List<MyObject> and thus, for all intents and purposes, IS A List<MyObject>.
The only thing you can do is to define a constructor on MyObjectCollection that takes an Ienumerable as a parameter and initalizes itself with the data in the other one, but that will make a new object containing the same data:
public class MyObjectCollection : List<MyObject>
{
public MyObjectCollection(IEnumerable<MyObject> items)
{
Addrange(items);
}
}
UPDATE:
As noted in the comment, you COULD have the cast succeed at runtime, provided that DoSomething actually returns an instance of MyObjectCollection. If it does, the object effectively is a MyObjectCollection, and the cast is completely legal.
I'd have to say, it is bad practice in my view to upcast something like that. If the function returns a List, you should not rely on a specific implementation of List. Either modify the return type of DoSomething, if you own that function, and return a MyObjectCollection, or deal with it as a list.
Without knowing what exactly is created inside DoSomething() we have to assume either:
You have a misunderstanding about the inheritence in .Net.
you have
A : B
B DoSomething()
{
return new B();
}
// then this is
B b = new B();
A a = (A)b;
Clearly b is a B but not an A. B might look much like A but it is not (if you traverse the parentage of b you won't find A anywhere)
This is true irrespective of the Generics involved (though that sometimes can cause situations where something that could work doesn't see the co-contra variance in c# 4.0)
or
A : B
B DoSomething()
{
return new A();
}
// then this is
B b = new A();
A a = (A)b;
Which in the absence of Generics will work.
You can't do it because (I guessing) the list instance returned from DoSomethingHere isn't derived from MyObjectCollection
You could create an implicit operator that would allow you to convert between your object and the list. You would need an constructor that takes a list and to property that returns the underlaying list.
public static implicit operator List<MyObject>(MyObjectCollection oCollection)
{
//Convert here
return MyObjectCollection.BaseList;
}
public static implicit operator MyObjectCollection(List<MyObject> oList)
{
//Convert here
return new MyObjectCollection(oList);
}

C# lambda expressions and lazy evaluation

One advantage of lambda expressions is that you have to evaluate a function only when you need its result.
In the following (simple) example, the text function is only evaluated when a writer is present:
public static void PrintLine(Func<string> text, TextWriter writer)
{
if (writer != null)
{
writer.WriteLine(text());
}
}
Unfortunately, this makes using the code a little bit ugly. You cannot call it with a constant or variable like
PrintLine("Some text", Console.Out);
and have to call it this way:
PrintLine(() => "Some text", Console.Out);
The compiler is not able to "infer" a parameterless function from the passed constant. Are there any plans to improve this in future versions of C# or am I missing something?
UPDATE:
I just found a dirty hack myself:
public class F<T>
{
private readonly T value;
private readonly Func<T> func;
public F(T value) { this.value = value; }
public F(Func<T> func) {this.func = func; }
public static implicit operator F<T>(T value)
{
return new F<T>(value);
}
public static implicit operator F<T>(Func<T> func)
{
return new F<T>(func);
}
public T Eval()
{
return this.func != null ? this.func() : this.value;
}
}
Now i can just define the function as:
public static void PrintLine(F<string> text, TextWriter writer)
{
if (writer != null)
{
writer.WriteLine(text.Eval());
}
}
and call it both with a function or a value.
I doubt that C# will get this feature, but D has it. What you've outlined is a suitable way to implement lazy argument evaluation in C#, and probably compiles very similarly to lazy in D, and in more pure functional languages.
All things considered, the four extra characters, plus optional white space, are not an exceptionally large price to pay for clear overload resolution and expressiveness in what is becoming a multi-paradigm strong-typed language.
The compiler is very good at inferring types, it is not good at inferring intent. One of the tricky things about all the new syntactic sugar in C# 3 is that they can lead to confusion as to what exactly the compiler does with them.
Consider your example:
() => "SomeText"
The compiler sees this and understands that you intend to create an anonymous function that takes no parameters and returns a type of System.String. This is all inferred from the lambda expression you gave it. In reality your lambda gets compiled to this:
delegate {
return "SomeText";
};
and it is a delegate to this anonymous function that you are sending to PrintLine for execution.
It has always been important in the past but now with LINQ, lambdas, iterator blocks, automatically implemented properties, among other things it is of the utmost importance to use a tool like .NET Reflector to take a look at your code after it is compiled to see what really makes those features work.
Unfortunately, the ugly syntax is all you have in C#.
The "dirty hack" from the update does not work, because it does not delay the evaluation of string parameters: they get evaluated before being passed to operator F<T>(T value).
Compare PrintLine(() => string.Join(", ", names), myWriter) to PrintLine(string.Join(", ", names), myWriter) In the first case, the strings are joined only if they are printed; in the second case, the strings are joined no matter what: only the printing is conditional. In other words, the evaluation is not lazy at all.
Well those two statements are completely different. One is defining a function, while the other is a statement. Confusing the syntax would be much trickier.
() => "SomeText" //this is a function
"SomeText" //this is a string
You could use an overload:-
public static void PrintLine(string text, TextWriter writer)
{
PrintLine(() => text, writer);
}
You could write an extension method on String to glue it in. You should be able to write "Some text".PrintLine(Console.Out); and have it do the work for you.
Oddly enough, I did some playing with lazy evaluation of lambda expressions a few weeks back and blogged about it here.
To be honest I don't fully understand your problem, but your solutions seems a tad complicated to me.
I think a problem I solved using lambda call is similar, maybe you could use it as inspiration: I want to see if a key exists in a dictionary, if not, I would need to execute a (costly) load operation.
public static class DictionaryHelper
{
public static TValue GetValueOrLambdaDefault<TKey, TValue> (this IDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> func)
{
if (dictionary.ContainsKey(key))
return dictionary[key];
else
return func.Invoke();
}
}
[TestClass]
public class DictionaryHelperTest
{
[TestMethod]
public void GetValueOrLambdaDefaultTest()
{
var dict = new Dictionary<int, string>();
try
{
var res1 = dict.GetValueOrLambdaDefault(1, () => LoadObject());
Assert.Fail("Exception should be thrown");
}
catch { /*Exception should be thrown*/ }
dict.Add(1, "");
try
{
var res1 = dict.GetValueOrLambdaDefault(1, () => LoadObject());
}
catch { Assert.Fail("Exception should not be thrown"); }
}
public static string LoadObject()
{
throw new Exception();
}
}