Inheritance and method invocation through an interface instance - c#-4.0

I've been reading "The C# Programming Language. 4th Edition" and found the following code sample:
interface I<T>
{
void F();
}
class Base<U>: I<U>
{
void I<U>.F() {...}
}
class Derived<U,V>: Base<U>, I<V>
{
void I<V>.F() {...}
}
...
I<int> x = new Derived<int,int>();
x.F();
Authors state that after calling x.F() the method in Derived will be invoked, because
"Derived<int,int> effectively reimplements I<int>"
I've checked with C# 4.0 compiler and found that this statement actually invokes the method in Base. Can you explain such behaviour?
Thanks in advance.
edit: here is the working code used for check:
using System;
interface I<T>
{
void F();
}
class Base<U>: I<U>
{
void I<U>.F()
{
Console.WriteLine("F() in Base");
}
}
class Derived<U,V>: Base<U>, I<V>
{
void I<V>.F()
{
Console.WriteLine("F() in Derived");
}
}
public class MainClass
{
public static void Main()
{
I<int> x = new Derived<int,int>();
x.F();
}
}
It outputs "F() in Base", so I don't know where I am wrong.

Because both Base and Derived interface from I.

void I<V>.F() {...} The method may be called/triggered from "Derived" but is executing the method defined in the interface.
void F();

Related

Calling Method/Function outside a Class but on the same namespace in c++/cli

I have a very simple and yet complicated (atleast for me) question on how to call a method/function outside a class but on a same namespace in c++/cli.
I know that you need to create an instance of an object before you can call a method which is inside a class, something like:
namespace Cars {
public ref class MyClass
{
void Honda(int i)
{
//some code
}
}
void Register()
{
MyClass c;
c.Honda(1);
//some code
}
}
But how do I do the opposite? Like how do I call Register() inside the MyClass::Honda function if they are on the same namespace but not on the same class?
I tried Cars::Register() but it gives an error saying that:
Register() is not a member of "Cars".
Edit: I added the actual code that I tried to access the Register() method.
namespace Cars {
public ref class MyClass
{
void Honda(int i)
{
Cars::Register();
}
}
void Register()
{
//some code
}
}
The line Cars::Register(); do not give any error when I save but when I try to rebuild my application it gives the error below:
Error C2039 'Register': is not a member of 'Cars'
Error C3861 'Register': identifier not found
Just to note that when I put Register() inside the MyClass, everything works well (for some reason I just need to put it outside the class)
Thanks!
There are 2 issues in your code:
Missing ; at the end of the definition for ref class MyClass.
Register() should be defined (or at least declared) before calling it.
Fixed version:
namespace Cars
{
// Defintion:
void Register()
{
//some code
}
public ref class MyClass
{
void Honda(int i)
{
Cars::Register();
}
};
}
Or alternatively:
namespace Cars
{
// Declaration:
void Register();
public ref class MyClass
{
void Honda(int i)
{
Cars::Register();
}
};
// Definition:
void Register()
{
//some code
}
}
Note: since you call Register within the same namespace, you can actually drop the Cars:: qualifier, i.e. simply call: Register();. You also keep it of course, if you think it improves readability.

How to call java function and pass arguments from c++ using Android NDK

I try to call a java function from my c++ code, but the app keeps 'crashing'.
At first, I start the c++ code through JNI call, which works without any problem. Then I let the function which is called executing the callback:
#include <jni.h>
extern "C"
JNIEXPORT jstring JNICALL
Java_net_example_folder_Service_startSomething(JNIEnv *env, jobject obj) {
invoke_class(env);
return env->NewStringUTF("The End.\n"); //works if I only use this line
}
Trying to follow http://www.inonit.com/cygwin/jni/invocationApi/c.html (and a lot of other guides/tips etc.), I use this to call the java function:
void invoke_class(JNIEnv* env) {
jclass helloWorldClass;
jmethodID mainMethod;
helloWorldClass = env->FindClass("Java/net/example/folder/helloWorldClass");
mainMethod = env->GetStaticMethodID(helloWorldClass, "helloWorld", "()V");
env->CallStaticVoidMethod(helloWorldClass, mainMethod);
}
To call the java code:
package net.example.folder;
import android.util.Log;
public class helloWorldClass {
public static void helloWorld() {
Log.e("helloWorldCLass", "Hello World!");
}
}
The c++ code is called by a background service. Here is the function of the Activity that starts it:
public void startService() {
Intent i = new Intent(this, Service.class);
startService(i);
}
And this is a part of the Service:
public class SimService extends IntentService {
...
#Override
protected void onHandleIntent(Intent intent) {
System.loadLibrary("native-lib");
startSomething();
}
}
That all works, but when I now change the function 'invoke_class' to:
void invoke_class(JNIEnv* env) {
jclass helloWorldClass;
jmethodID mainMethod;
helloWorldClass = env->FindClass("net/example/folder/helloWorldClass");
mainMethod = env->GetStaticMethodID(helloWorldClass, "helloWorld", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(helloWorldClass, mainMethod, env->NewStringUTF("some text"));
}
and of course the java part to:
package net.example.folder;
import android.util.Log;
public class helloWorldClass {
public static void helloWorld(String msg) {
Log.e("helloWorldCLass", msg);
}
}
With that, I'll get the earlier mentioned crash.
Why is that? How do I pass arguments correctly?
Symbol [ is used to represent arrays (as if you had String[] msg), remove that from your GetStaticMethodID method.
You can see more information about JNI Types and Data Structures here
Also as Michael said - you should check for java exceptions in your native code, because otherwise your app will crash. You can do it using Exception jni functions. For example:
jclass exClass = env->FindClass("some/random/class");
if (exClass == nullptr || env->ExceptionOccurred()) {
env->ExceptionClear();
// do smth in case of failure
}

Is the #Repeatable annotation not supported by Groovy?

I'm coding in Groovy and am having trouble with the Java 8 #Repeatable meta-annotation. I think I'm doing everything right, but it appears that Groovy is not recognizing #Repeatable. Here's my sample code; I'm expecting the information from both annotations to get stored in MyAnnotationArray:
import java.lang.annotation.*
class MyClass
{
#MyAnnotation(value = "val1")
#MyAnnotation(value = "val2")
void annotatedMethod()
{
println("annotated method called")
}
public static void main(String... args)
{
MyClass ob = new MyClass()
ob.annotatedMethod()
java.lang.reflect.Method m = ob.getClass().getMethod("annotatedMethod")
List annos = m.getAnnotations()
println("annos = $annos")
}
}
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#Repeatable(MyAnnotationArray)
public #interface MyAnnotation
{
String value() default "val0";
}
public #interface MyAnnotationArray
{
MyAnnotation[] MyAnnotationArray()
}
What happens is that I get this error:
Caught: java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface MyAnnotation: #MyAnnotation(value=val2)
java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface MyAnnotation: #MyAnnotation(value=val2)
Which is exactly what I get if I leave out the #Repeatable meta-annotation.
The code works fine if I leave out one of the duplicate MyAnnotations; then there is no error, and I then can read the annotation value as expected.
Is it possible that Groovy doesn't support the #Repeatable meta-annotation? I couldn't find any documentation that states this outright, though this page hints that maybe this is the case (scroll down to item 88).
seems to be not supported
i used java 1.8 and groovy 2.4.11
after compiling and de-compilig the same code i got this:
java:
#MyAnnotationArray({#MyAnnotation("val1"), #MyAnnotation("val2")})
public void annotatedMethod()
{
System.out.println("annotated method called");
}
groovy:
#MyAnnotation("val1")
#MyAnnotation("val2")
public void annotatedMethod()
{
System.out.println("annotated method called");null;
}
so, as workaround in groovy use
//note the square brackets
#MyAnnotationArray( [#MyAnnotation("val1"), #MyAnnotation("val2")] )
public void annotatedMethod()
{
System.out.println("annotated method called");
}
full script (because there were some errors in annotation declaration)
import java.lang.annotation.*
class MyClass
{
//#MyAnnotation(value = "val1")
//#MyAnnotation(value = "val2")
#MyAnnotationArray( [#MyAnnotation("val1"), #MyAnnotation("val2")] )
public void annotatedMethod()
{
System.out.println("annotated method called");
}
public static void main(String... args)
{
MyClass ob = new MyClass()
ob.annotatedMethod()
java.lang.reflect.Method m = ob.getClass().getMethod("annotatedMethod")
List annos = m.getAnnotations()
println("annos = $annos")
}
}
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#Repeatable(MyAnnotationArray)
public #interface MyAnnotation
{
String value() default "val0";
}
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotationArray
{
MyAnnotation[] value()
}
also tried against groovy 3.0.0-SNAPSHOT - the result is the same as for 2.4.11
Yes, Groovy has supported "repeatable" annotations for a long time even in Java 5 so long as retention policy was only SOURCE. This is what allows multiple #Grab statements for instance without the outer #Grapes container annotation. Being only retained in SOURCE makes them useful for AST transformations and within the Groovy compiler itself (and other source processors) but not really useful anywhere else. We don't currently support #Repeatable at all but plan to in a future version.

can't take address of function unless createing delegate instance

I have a class defined as below:
ref class myClass
{
PictureBox^ pic2;
public:
void setPic2() { pic2 = gcnew PictureBox; }
template<typename UnaryOperator>
void setPic2Click(Form^ x, UnaryOperator op) { pic2->Click += gcnew EventHandler(x, op); }
};
And in my Windows form class:
namespace testProject
{
public ref class Form1 : public System::Windows::Forms::Form
{
void Form1_Load(Object^ sender, EventArgs^ e)
{
rect1.setPic2();
rect1.setPic2Click(this, std::bind1st(std::mem_fun(&Form1::pic2_Click), this));
}
void pic2_Click(Object^ sender, EventArgs^ e)
{
// do something...
}
When compiled, it generated this error which is related to the rect1.setPic2Click call...:
error C3374: can't take address of 'testProject::Form1::pic2_Click' unless creating delegate instance
Basically, I tried to encapsulate the interface of the picturebox by create the instance method setPic2Click. Is this the right approach? Any suggestion how to remedy this error?
Your only mistake is that you're trying to mix managed and unmanaged C++/CLI code in a way that doesn't work (and doesn't make sense).
.NET delegates already have a bound first parameter. All you need is:
class1->setPic2Click(gcnew System::EventHandler(this, &Form1::pic2_Click));
and
void setPic2Click(System::EventHandler^ op) {pic2->Click += op;}

Use Groovy Category implicitly in all instance methods of class

I have simple Groovy category class which adds method to String instances:
final class SampleCategory {
static String withBraces(String self) {
"($self)"
}
}
I want to use this category in my unit tests (for example). It looks like this:
class MyTest {
#Test
void shouldDoThis() {
use (SampleCategory) {
assert 'this'.withBraces() == '(this)'
}
}
#Test
void shouldDoThat() {
use (SampleCategory) {
assert 'that'.withBraces() == '(that)'
}
}
}
What I'd like to achieve, however, is ability to specify that category SampleCategory is used in scope of each and every instance method of MyTest so I don't have to specify use(SampleCategory) { ... } in every method.
Is it possible?
You can use mixin to apply the category directly to String's metaClass. Assign null to the metaClass to reset it to groovy defaults. For example:
#Before void setUp() {
String.mixin(SampleCategory)
}
#After void tearDown() {
String.metaClass = null
}
#Test
void shouldDoThat() {
assert 'that'.withBraces() == '(that)'
}
Now you have the option to use extension modules instead of categories:
http://mrhaki.blogspot.se/2013/01/groovy-goodness-adding-extra-methods.html
On the plus side Intellij will recognize the extensions. I've just noticed that it doesn't even need to be a separate module as suggested by the link, just add META-INF/services/org.codehaus.groovy.runtime.ExtensionModule to the project:
# File: src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
moduleName = module
moduleVersion = 1.0
extensionClasses = SampleExtension
The extension class is pretty much defined like a normal category:
class SampleExtension {
static String withBraces(String self) {
"($self)"
}
}
Can be used like:
def "Sample extension"() {
expect: 'this'.withBraces() == '(this)'
}
If you are using Spock there is a #Use annotation that can be used on the specifications. The drawback with that is that Intellij will not recognize it.

Resources