There is a way to implement an abstract method of instance on initialization in C# like in Java?
public static abstract class A
{
public abstract String GetMsg();
public void Print()
{
System.out.println(GetMsg());
}
}
public static void main(String[] args)
{
A a = new A()
{
#Override
public String GetMsg()
{
return "Hello";
}
};
a.Print();
}
No you can't - but you can achieve the same end by using a Func<string>:
using System;
namespace Demo
{
public sealed class A
{
public Func<string> GetMsg { get; }
public A(Func<string> getMsg)
{
GetMsg = getMsg;
}
public void Print()
{
Console.WriteLine(GetMsg());
}
}
public static class Program
{
public static void Main()
{
var a = new A(() => "Hello");
a.Print();
}
}
}
Alternatively, if you want to be able to change the GetMsg property after initialization:
using System;
namespace Demo
{
public sealed class A
{
public Func<string> GetMsg { get; set; } = () => "Default";
public void Print()
{
Console.WriteLine(GetMsg());
}
}
public static class Program
{
public static void Main()
{
var a = new A(){ GetMsg = () => "Hello" };
a.Print();
}
}
}
(This uses c#6 syntax - you'd have to modify it slightly for earlier versions.)
Related
I have following code that does not compile
using System.Collections.Generic;
public interface IElement
{
}
public class AElement : IElement
{
public void DoSomethingSpecial()
{ }
}
public class Container<TElement>
{
public List<TElement> Elements { get; } = new();
}
public class Program
{
public static Container<IElement> GetContainer()
{
var concreteContainer = new Container<AElement>();
concreteContainer.Elements.ForEach(e => e.DoSomethingSpecial());
return concreteContainer; // Cannot implicitly convert type 'Container<AElement>' to 'Container<IElement>'
}
public static void Main()
{
var myContainer = GetContainer();
}
}
I read documentation about Covariance, Invariance, Contravariance and out Types.
And I am more confused than at the beginning.
Whats the way to fix this?
Code online: https://dotnetfiddle.net/85AgfT
You need to generate implicit conversion operator:
public class Container<IElement>
{
public List<IElement> Elements { get; } = new List<IElement>();
public static implicit operator Container<IElement>(Container<AElement> v)
{
//here you need to create Container<IElement> with your Container<AElement> 'v' values
return new Container<IElement>();
}
}
I finally got it working
using System.Collections.Generic;
public interface IContainer<out TElement>
{
}
public interface IElement
{
}
public class AElement : IElement
{
public void DoSomethingSpecial()
{ }
}
public class Container<TElement> : IContainer<TElement>
{
public List<TElement> Elements { get; } = new();
}
public class Program
{
public static IContainer<IElement> GetContainer()
{
var concreteContainer = new Container<AElement>();
concreteContainer.Elements.ForEach(e => e.DoSomethingSpecial());
return concreteContainer;
}
public static void Main()
{
var myContainer = GetContainer();
}
}
Make Container also an Interface and use an out Type parameter
using System;
public abstract class Astrodroid
{
public virtual string GetSound()
{
return "Beep beep";
}
public void MakeSound()
{
//this method should print the returned value of above function
}
}
In MakeSound method i have to print the value that is returned by the GetSound method.
You can call GetSound() from MakeSound. Here is an implementation.
class Program
{
public abstract class Astrodroid
{
public virtual string GetSound()
{
return "Beep beep";
}
public void MakeSound()
{
Console.WriteLine(this.GetSound());
Console.ReadLine();
}
}
public class MyClass:Astrodroid
{
}
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.MakeSound();
}
}
I have this object structure
public interface IHandler<in TMessage>
{
void HandleMessage(TMessage messageType);
}
public class MessageType1
{
}
public class MessageType2
{
}
public class HandlerMessageType1 : IHandler<MessageType1>
{
public void HandleMessage(T messageType)
{
}
}
public class HandlerMessageType2 : IHandler<MessageType2>
{
public void HandleMessage(T messageType)
{
}
}
and the registration
container.Collection.Register(typeof(IHandler<>), new[]
{
typeof(HandlerMessageType1),
typeof(HandlerMessageType2)
});
how the constructor of the class where this is injected should look like?
public class ClientClass
{
public ClientClass(IEnumerable<IHandler<>> handlers)
{
}
}
like this doesn't work... how the signature of the client class constructor should look like?
this was edited to improve the example.
tkx in advance
Paulo Aboim Pinto
I Know if I understood, but with unity you can have:
public class Handler1 : IHandler
{
public void HandlerType()
{
Console.WriteLine("Handler1");
}
}
public class Handler2 : IHandler
{
public void HandlerType()
{
Console.WriteLine("Handler2");
}
}
public interface IHandler
{
void HandlerType();
}
Unity configuration
public static class DependencyConfiguration
{
public static UnityContainer Config()
{
var unity = new UnityContainer();
unity.RegisterType<IHandler, Handler1>("Handler1");
unity.RegisterType<IHandler, Handler2>("Handler2");
unity.RegisterType<IEnumerable<IHandler>>();
return unity;
}
}
A class to resolve:
public class ListOfTypes
{
private List<IHandler> handlers;
public ListOfTypes(IEnumerable<IHandler> handlers)
{
this.handlers = handlers.ToList();
}
public void PrintHandlers()
{
handlers.ForEach(_ => _.HandlerType());
}
}
The program:
static void Main(string[] args)
{
Console.WriteLine("Resolve sample");
var unity = DependencyConfiguration.Config();
var lstOfTypes = unity.Resolve<ListOfTypes>();
lstOfTypes.PrintHandlers();
Console.ReadLine();
}
Result:
For background I mainly program in Java and am trying to work with/learn generics in a C# project and got stuck.
Here is my problem. From the main method you can see I am trying to set the soldiers task, but I'm getting the error,
cannot convert from 'TaskHeal' to 'TaskBase<SoldierBase>'
It seems that this cast should work as TaskHeal is a child of TaskBase, but it doesn't. Here is my complete code:
public class Main {
static void main(string[] args) {
SoldierMedic myMedic = new SoldierMedic();
myMedic.setTask(new TaskHeal(myMedic)); // Problem!
}
}
public class SoldierBase {
private TaskBase<SoldierBase> currentTask;
public int status;
public void setTask(TaskBase<SoldierBase> newTask) {
this.currentTask = newTask;
}
}
public class SoldierMedic : SoldierBase {
public int healRate = 45;
}
public abstract class TaskBase<T> where T : SoldierBase {
protected T soldier;
public TaskBase(T unit) {
this.soldier = unit;
this.soldier.status = 1;
}
public abstract void preformTask();
}
public class TaskHeal : TaskBase<SoldierMedic> {
public TaskHeal(SoldierMedic unit) : base(unit) { }
public override void preformTask() {
this.soldier.healRate++;
}
}
If you don't mind having an additional base, non-generic class for TaskBase and SoldierBase, you could do this:
class Program
{
static void Main(string[] args)
{
var myMedic = new SoldierMedic();
myMedic.setTask(new TaskHeal(myMedic)); // Problem!
}
}
public class SoldierBase
{
public int status;
}
public class SoldierBase<T> : SoldierBase where T : SoldierBase
{
private TaskBase currentTask;
public void setTask(TaskBase newTask)
{
this.currentTask = newTask;
}
}
public class SoldierMedic : SoldierBase<SoldierMedic>
{
public int healRate = 45;
}
public abstract class TaskBase
{
}
public abstract class TaskBase<T> : TaskBase where T : SoldierBase<T>
{
protected T soldier;
public TaskBase(T unit)
{
this.soldier = unit;
this.soldier.status = 1;
}
public abstract void preformTask();
}
public class TaskHeal : TaskBase<SoldierMedic>
{
public TaskHeal(SoldierMedic unit) : base(unit) { }
public override void preformTask()
{
this.soldier.healRate++;
}
}
If you want this to look more like c# (using properties, proper access modifiers and casing), you'd do something like this:
class Program
{
static void Main(string[] args)
{
var myMedic = new SoldierMedic();
myMedic.CurrentTask = new TaskHeal(myMedic); // Problem!
}
}
public class SoldierBase
{
public int Status { get; set; }
}
public class SoldierBase<T> : SoldierBase where T : SoldierBase
{
public TaskBase CurrentTask { get; set; }
}
public class SoldierMedic : SoldierBase<SoldierMedic>
{
public int HealRate { get; set; } = 45;
}
public abstract class TaskBase
{
}
public abstract class TaskBase<T> : TaskBase where T : SoldierBase<T>
{
protected T Soldier;
public TaskBase(T unit)
{
Soldier = unit;
Soldier.Status = 1;
}
public abstract void PerformTask();
}
public class TaskHeal : TaskBase<SoldierMedic>
{
public TaskHeal(SoldierMedic unit) : base(unit) { }
public override void PerformTask()
{
Soldier.HealRate++;
}
}
Due to the polymorphism property of the classes, below example will print AB twice, which is expected.
In my case, I really want it to print A then AB.
I decided to change the Get() method in B from overrides to new.
This solves my problem, but they informed me of bad practise, so I'm looking for an alternative...
The one thing that comes to mind is to instantiate a new A in B.Do(), which I think is also bad practise...
//ORIGINAL
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Do();
}
}
public class A
{
public virtual void Do()
{
var get = Get();
Console.WriteLine(get);
}
public virtual string Get()
{
return "A";
}
}
public class B : A
{
public override void Do()
{
base.Do();
var get = Get();
Console.WriteLine(get);
}
public override string Get()
{
return base.Get() + "B";
}
}
//UPDATED, USING NEW
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Do();
Console.ReadLine();
}
}
public class A
{
public virtual void Do()
{
var get = Get();
Console.WriteLine(get);
}
public virtual string Get()
{
return "A";
}
}
public class B : A
{
public override void Do()
{
base.Do();
var get = Get();
Console.WriteLine(get);
}
public new string Get()
{
return base.Get() + "B";
}
}
Instead of calling the base version of Do in B.Do, you can change the implementation as follows:
public class B : A
{
public override void Do()
{
// Call the base version of Get explicitly
var getBase = base.Get();
Console.WriteLine(getBase);
// Call the current implementation of Get
var get = Get();
Console.WriteLine(get);
}
public override string Get()
{
return "B";
}
}
This will technically solve your problem, but is not a really clean solution from an OOP point of view. I suggest to think a bit about whether you need to be able to override Get independently. Maybe changing the signatures of your methods so that Get always returns a list of strings that should be printed is also a good solution (I've renamed Get to GetLines to reflect the changed purpose of the method):
public class A
{
public virtual void Do()
{
var lines = GetLines();
foreach(var line in lines)
Console.WriteLine(line);
}
public virtual IEnumerable<string> GetLines()
{
return new string[] { "A" };
}
}
public class B : A
{
public override IEnumerable<string> GetLines()
{
var lst = new List<string>(base.GetLines());
lst.Add("B");
return lst;
}
}
Here is the corrected code:
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Do();
}
}
public class A
{
public virtual void Do()
{
Console.WriteLine(Get());
}
public virtual string Get()
{
return "A";
}
}
public class B : A
{
public override void Do()
{
Console.WriteLine(base.Get());
base.Do();
}
public override string Get()
{
return base.Get() + "B";
}
}