In Java I'm able to have a class like this:
public abstract class Button{
public abstract void onClick();
}
Then initialize it by using:
Button b = new Button(){
#Override
public void onClick(){
// Things
}
}
Now is there any way to do a similar thing in C#?
Or would my best bet be to use an event?
If you want to use Abstract Class you need to have another class inherited from that Abstract Class and use it to initialize abstract class like this:
public class MeSecondClass : MyClass
{
public override void OnClick(object sender, EventArgs args)
{
throw new NotImplementedException();
}
}
public abstract class MyClass
{
public abstract void OnClick(object sender, EventArgs args);
}
MyClass a = new MeSecondClass();
The comparable approach in C# to Java's anonymous inner classes feature is to instantiate a dynamic object and convert it to the abstract class. Unfortunately you have to implement the conversion yourself.
Example:
using System;
namespace AnonymousInnerClassExample
{
class Program
{
public static void Main(string[] args)
{
Button button = Button.CreateFromDynamic(new
{
OnClick = new Action(() =>
{
Console.WriteLine("Hit OnClick");
})
});
button.OnClick();
}
public abstract class Button
{
public abstract void OnClick();
public static Button CreateFromDynamic(dynamic button)
{
return new Implementation(button);
}
private class Implementation : Button
{
public Implementation(dynamic button)
{
PrivateOnClick = button.OnClick;
}
private Action PrivateOnClick { get; set; }
public override void OnClick()
{
PrivateOnClick();
}
}
}
}
}
Just for anyone else trying to do something similar. #shmosel suggested lambdas, and so that is what I used.
public class Button(){
private Action _onClick;
public Button(Action onClick){
_onClick = onClick;
}
//Other method that calls _onClick()
}
//Other Class
Button b = new Button(() => {/*Do Code Here*/});
As the other answers show, you CAN do something similar, but really the question is 'Should you?' and the answer is no.
Events were created for just this sort of thing, so use an event. Not only is it clearer and cleaner code, but it is a well established pattern that C# devs will know, so using it help with maintainability of your code.
Related
In java, I'd like to do something like this
public class Tata{
public static void f(){
//something
}
public static void g(){
//something
}
}
public class Titi{
public static void f(){
//something
}
public static void g(){
//something
}
}
public class Toto{
private Class c = Tata.class; //or Titi.class
public static void main(String[] args) {
c.f();
c.g();
}
}
To be precise, I'd like to be able to freely switch between classes Tata and Titi, to use their respective methods f or g.
This doesn't work as intended, as I get the cannot resolve method 'f()' error. Simply replacing c.f(); and c.g(); with Tata.f(); and Tata.g(); works fine, but defeats the purpose of using a parameter. How to solve this?
Will turn the comment into answer after all.. The correct (Java) way to deal with what you want is the use of interface. So in your demo code the implementation would be the following:
public interface TheFGFunctions {
void f();
void g();
}
public class Tata implements TheFGFunctions {
#Override
public void f() {
//something
}
#Override
public void g() {
//something
}
}
public class Titi implements TheFGFunctions {
#Override
public void f() {
//something
}
#Override
public void g() {
//something
}
}
public class Toto {
private TheFGFunctions c;
public Toto(TheFGFunctions c) {
this.c = c;
}
public void notStaticFunction() {
c.f();
c.g();
}
}
This way is totally typesafe with zero exceptions to deal with!
You cannot access a static method polymorphically. The Java language doesn't support it.
The reason your current approach fails is that c is an instance of the class Class, and the class Class doesn't define methods f() or g().
(The methods that it does define are listed in the javadoc for Class. Note that Class is final so you can't create a custom subclass with extra methods.)
The simple alternative is to use reflection; e.g.
Class c =
Method f = c.getMethod("f");
f.invoke(null); // because it is static
But note:
This is not statically type-safe. The compiler cannot tell when you make the mistake of trying to use a static f() on a class that doesn't have such a method.
There are a few exceptions that you need to deal with; e.g. missing methods, incorrect signatures, methods that are not static, methods that don't have the correct access.
Other answers have proposed creating an interface and wrapper classes to make certain static methods dispatchable. It will work and it will be compile-time type-safe (!) but there is a lot of boiler plate code to write.
#Michael Michailidis commented:
Thus interfaces!
Yea ... kind of. You can only dispatch polymorphically on instance methods declared on an interface. That implies that you must have an instance of Tata or Titi, and call the methods on it. My reading of the Question is that the author wants to avoid that.
(IMO, the avoidance is the real problem. You are better of not trying to avoid instance methods.)
FWIW, you can declare static methods in an interface (since Java 8), but they would behave the same as if you declared them in a class. You wouldn't be able to dispatch ...
You could use reflections:
private Class c = Tata.class;
public Toto() throws Exception {
c.getMethod("f").invoke(null);
c.getMethod("g").invoke(null);
}
Here my Tata class
public class Tata {
public static void f() {
System.out.println("ffff");
}
public static void g() {
System.out.println("gggg");
}
}
Output on new Toto() call:
ffff
gggg
Update (call with parameters):
public Toto() throws Exception {
c.getMethod("f", String.class).invoke(null, "paramValue1");
c.getMethod("g", String.class).invoke(null, "paramValue2");
}
public class Tata {
public static void f(String param1) {
System.out.println("ffff " + param1);
}
public static void g(String param2) {
System.out.println("gggg " + param2);
}
}
Output:
ffff paramValue1
gggg paramValue2
Write a wrapper interface
interface CWrapper {
void f();
void g();
}
and wrapper class factory method for each Class containing the methods
class CWrappers {
CWrapper forTiti(Class<Titi> titiClass) {
return new CWrapper() {
void f() { Titi.f(); }
void g() { Titi.g(); }
}
}
// another factory method for Tata
}
Then you can use that:
public class Toto {
private CWrapper c = CWrappers.forTata(Tata.class); //or forTiti(Titi.class)
public static void main(String[] args) {
c.f();
c.g();
}
}
I have to send this to another class
I need void in my activity like this:
mStrawberry.foo(this)
and inside Strawberry
public class Strawberry{
public Strawberry(){}
foo( ????? thisVariable ){
//work with this...
}
}
I know this is MainActivity.this bud I have to use different class not only MainActivity...
Thank you for the reply
Just declare a parameter of the appropriate type (whatever this is in the code mStrawberry.foo(this)):
public class Strawberry{
public Strawberry(){}
foo(TheRelevantType thisVariable ){ // ***
thisVariable.doSomething(); // ***
}
}
In the above, I've used TheRelevantType.
I know this is MainActivity.this bud I have to use different class not only MainActivity...
If you need to have a method that accepts instances of two different classes, you do that by having both classes implement an interface with the common aspects you need to use:
interface ActivityCommon {
void doSomething();
}
class ThisActivity implements ActivityCommon {
public void doSomething() {
System.out.println("This is ThisActivity's doSomething");
}
}
class ThatActivity implements ActivityCommon {
public void doSomething() {
System.out.println("This is ThatActivity's doSomething");
}
}
class Strawberry {
foo(ActivityCommon common) {
common.doSomething();
}
}
...and/or use a common base class, which looks very similar:
class ActivityBase extends Activity { // Or whatever the base should be
abstract void doSomething();
}
class ThisActivity extends ActivityBase {
#Override
public void doSomething() {
System.out.println("This is ThisActivity's doSomething");
}
}
class ThatActivity extends ActivityBase {
#Override
public void doSomething() {
System.out.println("This is ThatActivity's doSomething");
}
}
class Strawberry {
foo(ActivityBase activity) {
activity.doSomething();
}
}
I'll show the rudimentary approach of Object as you seem to be unaware of how Java works. You can use Generics as well but it will go over your head and you will blunder around before actually understanding how it works.
foo(Object passedActivity){
//Object is the base class to all classes in java and can refer to anything
if(passedActivity instanceof FirstActivity){
FirstActivity fref = (FirstActivity)passedActivity;
//modify the data now using fref
//fref.finish(); or any other similar thing
}else if(passedActivity instanceof SecondActivity){
SecondActivity sref=(SecondActivity)passedActivity;
//modify using sref now
//sref.finish(); or any other similar thing
}else{
Log.d("Error","Please pass a valid Activity");
}
}
I am not sure how am I suppose to go about my question. It is about Android can Instantiate Interface. I am trying to do in C#. Now I am pretty sure that the rules for both Java and C# is you can't create an Instance of abstract and Interface as being said.
But I would really like to know how Android does this practice.
In Android you can do this.
public interface Checkme{
void Test();
void Test2();
}
public void myFunc(Checkme my){
//do something
}
// Now this is the actual usage.
public void Start(){
myFunc(new Checkme(){
#Override
public void Test()
{
}
#Override
public void Test2()
{
}
});
}
Actually once you press Enter on new Checkme() You will automatically get the Override methods of the Interface. Like auto Implement method of an Interface in C#.
I hope my question make sense.
C# doesn't support anonymously auto-implemented interfaces because it has delegates:
public void Foo(Func<string> func, Action action) {}
// call it somewhere:
instance.Foo(() => "hello world", () => Console.WriteLine("hello world"));
With delegates you can fill the gap and it can be even more powerful than implementing interfaces with anonymous classes.
Learn more about delegates.
This is an Anonymous Class:
public void Start(){
myFunc(new Checkme() {
#Override
public void Test() {
}
#Override
public void Test2() {
}
});
}
An anonymous class is an unnamed class implemented inline.
You could also have done it using a Local Class, but those are rarely seen in the wild.
public void Start(){
class LocalCheckme implements Checkme {
#Override
public void Test() {
}
#Override
public void Test2() {
}
}
myFunc(new LocalCheckme());
}
These both have the advantage that they can use method parameters and variables directly, as long as they are (effectively) final.
As a third option, you could do it with an Inner Class.
private class InnerCheckme implements Checkme {
#Override
public void Test() {
}
#Override
public void Test2() {
}
}
public void Start(){
myFunc(new InnerCheckme());
}
An inner class cannot access method variables (obviously because it's outside the method), but can be used by multiple methods.
Any local values from the method can however be passed into the constructor and stored as fields of the inner class, to get the same behavior. Just requires a bit more code.
If the inner class doesn't need access to fields of the outer class, it can be declared static, making it a Static Nested Class.
So, all 3 ways above a very similar. The first two are just Java shorthands for the third, i.e. syntactic sugar implemented by the compiler.
C# can do the third one, so just do it that way for C#.
Of course, if the interface only has one method, using a Java lambda or C# delegate is much easier than Anonymous / Local / Inner classes.
If I understand correcly, you're defining a class that implements an interface, and when you specify that the class implements an interface, you want it to automatically add the interface's methods and properties.
If you've declared this:
public interface ISomeInterface
{
void DoSomething();
}
And then you add a class:
public class MyClass : ISomeInterface // <-- right-click
{
}
Right-click on the interface and Visual Studio will give you an option to implement the interface, and it will add all the interface's members to the class.
you mean something like this?
pulic interface Foo{
void DoSomething();
}
public class Bar : Foo {
public void DoSomething () {
//logic here
}
}
myFunc(new Checkme(){
#Override
public void Test()
{
}
#Override
public void Test2()
{
}
});
You're passing into myFunc() something that is called an anonymous class. When it says "new Checkme() { .... }", it is defining an anonymous implementation of the Checkme interface. So, it's not an instance of the interface itself, just an instance of a type that implements it.
In C# anonymously implemented classes for Interface are not auto generated just like in java, you need to follow the below procedure to workout.
public class MyClass {
public void someMethod (string id, IMyInterface _iMyInterface) {
string someResponse = "RESPONSE FOR " + id;
_iMyInterface.InterfaceResponse (someResponse);
}
}
public interface IMyInterface {
void InterfaceResponse (object data);
void InterfaceResponse2 (object data, string x);
}
public class MyInterfaceImplementor : IMyInterface {
private readonly Action<object> actionname;
private readonly Action<object, string> actionInterfaceResponse2;
public MyInterfaceImplementor (Action<object> InterfaceResponse) {
this.actionname = InterfaceResponse;
}
public MyInterfaceImplementor(Action<object> interfaceResponseMethod, Action<object, string> interfaceResponseMethod1) {
this.actionname = interfaceResponseMethod ?? throw new ArgumentNullException(nameof(interfaceResponseMethod));
this.actionInterfaceResponse2 = interfaceResponseMethod1 ?? throw new ArgumentNullException(nameof(interfaceResponseMethod1));
}
public void InterfaceResponse (object data) {
this.actionname (data);
}
public void InterfaceResponse2(object data, string x) {
this.actionInterfaceResponse2(data, x);
}
}
Gist Source : https://gist.github.com/pishangujeniya/4398db8b9374b081b0670ce746f34cbc
Reference :
I want to be able to subclass some values in an enum, in order that I don't have to repeat code too much. Is there some way I can do this? Here's an example of what I want to achieve, which Eclipse quickly tells me is an abomination:
public enum Foo {
BAR {
#Override
public void taskA() {
System.out.println("A");
}
#Override
public void taskB() {}
},
BAZ extends BAR {
#Override
public void taskB() {
System.out.println("B");
}
};
public abstract void taskA();
public abstract void taskB();
}
BAR would have only the implementation of taskA and an empty taskB, and BAZ would have both methods - BAR's implementation of taskA, and its own implementation of taskB.
I'm not changing the values of the enum after it's declared, so why doesn't this work? I could call BAR's taskA method within BAZ, so why can't I do this?
I want to be able to subclass some values in an enum, in order that I
don't have to repeat code too much.
The usual way to share code among constant-specific methods is to declare a private static method (either in the enum itself or in a utility helper class) which contains the common code that you wish to access from your constant-specific methods.
For example ...
public enum Foo {
BAR {
#Override
public void taskA() {
commonToTaskAandB();
System.out.println("B");
}
#Override
public void taskB() {}
},
BAZ {
#Override
public void taskB() {
commonToTaskAandB();
System.out.println("B");
}
};
public abstract void taskA();
public abstract void taskB();
private static void commonToTaskAandB() {
// shared code here
:
:
}
}
Note that the code "BAZ extends Bar" is illegal because BAZ is not a type. BAZ is an instance of your Enum<Foo> type. An instance cannot extend another type. It is incorrect to apply object-oriented principles like inheritance to enum constants because, in Java, enum constants are instances of a class and not classes themselves.
Enum-Constants are objects (instances), not classes. You can only subclass classes.
However even that will not work: you can only extend enums with anynomous inner classes.
You will have to find another solution for your use case. You could:
use a static method for the shared code
call BAR.taskA() in BAZ
make taskA not abstract and put your code there
use normal constants, instead of enums
But my favorit is:
inject behaviour instead of overriding!
Example code:
class Behavior {
public static Runnable A = new Runnable() {
public void run() {
System.out.println("A");
}
}
public static Runnable B = new Runnable() {
public void run() {
System.out.println("B");
}
}
public static Runnable DO_NOTHING = new Runnable() {
public void run() {
}
}
}
public enum Foo {
BAR(Behavior.A, Behavior.DO_NOTHING),
BAZ(Behavior.A, Behavior.B);
private final Runnable mechanismA;
private final Runnable mechanismB;
private Foo(Runnable mechanismA, Runnable mechanismB) {
this.mechanismA = mechanismA;
this.mechanismB = mechanismB;
}
public void taskA() {
mechanismA.run;
}
public void taskB() {
mechanismB.run;
}
}
Pros of this solution:
The code explicitly defines the behavior of each enum constant - no implicit calculations => easier to read
You can use inheritance, etc in the Behavior-class
You can easily switch behaviorA and behaviorB - or reuse that code anywhere else
If you have Java8 available you can even shorten the code to this:
public static Runnable A = () -> {
System.out.println("A");
};
I am writing a library in Java, which throws an event of different types with differing data depending on the type.
For example, here is the extended EventObject:
public class FooEvent extends EventObject {
private final int eventType;
private final Object fooEventObject;
public FooEvent(int type, Object obj){/*...*/}
public int getEventType() {/*...*/}
public int getEventObject() {/*...*/}
}
And here is how I my listener currently looks like:
FooEventListener listener = new FooEventListener() {
#Override
public void onDataChange(FooEvent event) {
switch(event.getEventType()) {
case EVENT_TYPE_BAR:
Bars bar = (Bars)event.getEventObject();
/*work with Bar object...*/
break;
case EVENT_TYPE_GOO:
Goo goo = (Goo)event.getEventObject();
/*work with Goo object...*/
break;
/* etc ...*/
}
}
}
I would like to know if this is the right way of solving this problem (although I doubt it is, since the user of the library would need to know what type to cast to) wherein I have different event types with objects and I do not want to go and make a different event & listener for each one.
Guava's EventBus provides a slightly different approach that can handle multiple event types.
There is unfortunately no easy solution to have a type safe event system with different types. You either have to have 1 listener / publishing implementation per type of you need to teach one side about all the event types that exist.
There is a way to remove the need for instanceof or switch (type) and casting though: the Visitor Pattern
The pattern uses the fact that event objects know their own type which means they can call the right method. The downside is that you need a listener interface that contains all the types.
public class Test {
abstract static class EventObject {
protected abstract void deliver(EventListener listener);
}
static class AEvent extends EventObject {
#Override
protected void deliver(EventListener listener) {
listener.onAEvent(this);
}
}
static class BEvent extends EventObject {
#Override
protected void deliver(EventListener listener) {
listener.onBEvent(this);
}
}
interface EventListener {
void onAEvent(AEvent event);
void onBEvent(BEvent event);
// ...
}
private static final EventListener LISTENER = new EventListener() {
#Override
public void onBEvent(BEvent event) {
System.out.println("Got B Event! " + event);
}
#Override
public void onAEvent(AEvent event) {
System.out.println("Got A Event! " + event);
}
};
private static void notifyListeners(EventObject event) {
event.deliver(LISTENER);
}
public static void main(String[] args) {
notifyListeners(new AEvent());
notifyListeners(new BEvent());
}
}
A better way to solve this is with generics.
public class FooEvent<T> extends EventObject {
private final T fooEventObject;
public FooEvent(T obj){/*...*/}
public T getEventObject() {/*...*/}
}
//usage
SomeType object = new SomeType();
new FooEvent<SomeType>(object);
I think it's a way to go, but not the cleanest way. You should create an abstract class
public abstract class AbstractEventType<T> extends EventObject {}
and extend from that:
public abstract class FooEvent extends AbstractEventType<Foo> {}
public abstract class BarEvent extends AbstractEventType<Bar> {}
Then you need to fire different events and also have different event listeners based on the type:
public interface FooEventListener {
public void onFooChange(FooEvent fooEvent);
}
etc.
If you want to stick with only one event type then you could at least move the code to determine the type to your framework and avoid pollution of the "business" code, by creating one handler method per type, e.g.
public interface MyEventListener {
public void onFooChange(EventType<Foo> eventType);
public void onBarChange(EventType<Bar> eventType);
}