Covariance Pattern for Abstract Classes - c#

I'm realizing now that covariance is not available in abstract classes but is there anyway that I can utilize it here so that I can continue with this pattern.
Basically want the ability to create an instance of the first generic argument and pass the object which creates this object itself.
The below will fail at runtime because SpecialProcessor cannot be assigned to ProcessorBase with respect to generic types.
Appreciate any suggestions.
public class ProcessorUser<T> where T : ProcessorBase
{
public void ReceiveCommand()
{
Activator.CreateInstance(typeof (T), this);
}
}
public abstract class ProcessorBase
{
protected ProcessorBase(ProcessorUser<ProcessorBase> param)
{
}
}
public class SpecialProcessor : ProcessorBase
{
public SpecialProcessor(ProcessorUser<ProcessorBase> param)
: base(param)
{
}
}

Actually, from your less-than-complete code example, it's not clear at all a) what you are trying to do, and b) what "fails at runtime". You didn't show any code that calls the ReceiveCommand() method, so it's impossible to see in what way that code might fail.
That said, the usual way to gain access to variance in C# is through delegate or interface types. So you can declare a covariant interface to be implemented by ProcessorUser<T>, and then use that interface in the constructor declarations instead of the actual type. For example:
interface IProcessorUser<out T> where T : ProcessorBase
{
void ReceiveCommand();
}
class ProcessorUser<T> : IProcessorUser<T> where T : ProcessorBase
{
public void ReceiveCommand()
{
Activator.CreateInstance(typeof(T), this);
}
}
abstract class ProcessorBase
{
protected ProcessorBase(IProcessorUser<ProcessorBase> param)
{
}
}
class SpecialProcessor : ProcessorBase
{
private IProcessorUser<SpecialProcessor> _param;
public SpecialProcessor(IProcessorUser<SpecialProcessor> param)
: base(param)
{
_param = param;
}
public void ReceiveCommand() { _param.ReceiveCommand(); }
}
Note that I added the ReceiveCommand() method to the SpecialProcessor class just so I could see something execute at run-time. And that something does in fact work. But there's no way for me to know whether in your scenario, this is what you wanted to happen. You'd have to provide a good, minimal, complete code example that clearly shows what you are trying to do and what difficulty you are having doing it, if you want a clear, precise answer to that aspect of it.
(By the way, this really doesn't have anything to do with abstract classes. There's not even anything in your code example that is actually abstract, other than the class declaration itself, and the general principle applies to any class, not just abstract ones).

Related

OOP Design: Concrete Class having different Operations with Same Base Class

I am wondering if the following code can be written in C#:
AbstractClass a = new ConcreteClass1();
a.Operations.Method1();
AbstractClass b = new ConcreteClass2();
b.Operations.Method2();
where Method1() is exclusive to the ConcreteClass1 instance and Method2() is exclusive to the ConcreteClass2() instance. As a result, a.Operations.Method2() and b.Operations.Method1() would be invalid.
This is not possible by design - a and b have the same type, and the compiler will treat them as such. The only way to make it work is by using runtime exceptions.
The concept behind using abstract classes or interfaces conflicts with what you are attempting to do; it sounds like ConcreteClass1 and ConcreteClass2 do not server the same purpose, should they still use the same abstract base class?
I don't know what exactly you are trying to do - so I'll provide a few options:
Use interfaces to show that specific classes implement specific operations:
interface IOperation1
{
void Operation1();
}
interface IOperation2
{
void Operation2();
}
Then reference the interfaces based on what you are trying to achieve.
If Method1 and Method2 are supposed to be invoked at the same time, consider a design where AbstractClass declares the method to be invoked, and the concrete classes do different operations based on that:
abstract class AbstractClass
{
...
abstract void DoSomeOperation();
}
class ConcreteClass1
{
override void DoSomeOperation()
{
this.Operations.Method1();
}
}
class ConcreteClass2
{
override void DoSomeOperation()
{
this.Operations.Method2();
}
}
It's okay for ConcreteClass1 and ConcreteClass2 to have some different methods, but share some functionality that they both inherit from AbstractClass. (If you cast them as their base type then you can only call common methods that they inherit from the base type.)
It sounds like the difference between whether a concrete class uses Method1 or Method2 is an internal detail that should be handled inside the class. The class should know what method it needs to call. In fact, does a consumer of that class even need to know that it depends on Operations? Probably not. Consumers should just call a method on the class, and then whether that class uses Operations.Method1, Operations.Method2, or even depends on Operations at all is an internal implementation detail.
Maybe what you want is something like this:
public abstract class AbstractClass
{
public abstract void DoSomething();
}
public class Operations
{
public void Method1()
{
//Does something
}
public void Method2()
{
//Apparently does something comopletely different
}
}
public class ConcreteClass1 : AbstractClass
{
private Operations _operations;
public override void DoSomething()
{
_operations.Method1();
}
}
public class ConcreteClass2 : AbstractClass
{
private Operations _operations;
public override void DoSomething()
{
_operations.Method2();
}
}
Operations should only be in the base class if it's required that every derived class will use it. (That doesn't happen too much. If all of the derived classes have the same behavior, why isn't it in the base class?) If that's the case then you can hide it in the base class, like this:
public abstract class AbstractClass
{
private Operations _operations;
protected Operations Operations { get { return _operations; } }
public abstract void DoSomething();
}
That way it's exposed to the derived classes but hidden from everything else.

Overriding (shadowing, overloading?) methods with different return types in a C# hierarchy

I'm writing an SDK which has an OOP structure for implementing data types;
first an interface
then an abstract implementation
finally an abstract generic implementation
People can choose to implement either the interface, or derive from either of the classes.
public interface IGoo
{
IGoo Duplicate();
...
}
public abstract class Goo : IGoo
{
IGoo IGoo.Duplicate() {
return Duplicate();
}
abstract public Goo Duplicate();
...
}
public abstract class Goo<T> : Goo
{
abstract public Goo<T> Duplicate(); ??????
...
}
I'd like to re-implement the Duplicate method so that it always returns the most specific type possible. I.e. when you call Duplicate on an IGoo instance, you get another IGoo. If you call it on Goo, you get Goo, if you call it on -say- Goo<int>, you get Goo<int>. And all Duplicate() methods always call the most specific implementation.
Is this possible? Is it only possible when you can implement an interface explicitly? In which case, should I not make Goo<int> derive from Goo, but have it implement IGoo instead and type all the low-level functionality twice?
What about the following?
public interface IObj
{
IObj Duplicate();
}
public abstract class Obj : IObj
{
public Obj()
{
}
public virtual IObj Duplicate()
{
return this;
}
}
public abstract class ObjT<T> : Obj
{
public ObjT()
{
}
public override IObj Duplicate()
{
return this;
}
}
public class ObjImpl : Obj
{
}
public class ObjTImpl : ObjT<int>
{
}
I understand that you want it to return the most specific type possible in any inheriting class but it actually is. It's boxing the inheriting type into the interface (or a raw object if you where to return objects instead of interface types. If you run the following test in a console app you will see the proper type is represented:
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
ObjImpl a = new ObjImpl();
ObjTImpl b = new ObjTImpl();
Console.WriteLine(a.Duplicate().GetType());
Console.WriteLine(b.Duplicate().GetType());
Console.ReadLine();
}
}
}
// outputs:
// ObjImpl
// ObjTImpl
The idea of redefining abstracts of abstracts goes against the purpose of abstract polymorphism. If the derived types do not intend to implement the inherited abstract member, they should not be inheriting it.
Although the example I gave above would require casting to access any child class-specific members, it would be the proper way to do it in this approach. The runtime needs to know what types it should expect to deal with.
There is always dynamics you could play around with but to be honest I haven't played around with dynamics with generics and inheritance as I suspect I would make my compiler cry, and when it cries, I cry, a little bit deep down inside... lol
It is only possible when you implement the interface explicitly. That's because the return type of a method is not part of its signature - which the compiler checks when overloading. Therefore, otherwise identical methods which only differ in their return type are syntactically not possible.

Specify generic type as argument param without knowing T

I'm approaching a problem while still having some ignorance regarding Generics and their proper declarations / uses. I get the premiss, but some of the ins-n-outs of generics still elude me.
Given the following code (does not compile and contains code-smell):
public interface IUIConcern<out T> where T : IUIConcernExtension
{
string Name { get; }
Func<T> Extend();
}
public class UIConcern
{
public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension
{
Concerns.Add(uiConcern);
}
public static List<IUIConcern<T>> Concerns{
get {
// Logic...
}
set {
// Logic...
}
}
}
... I have a few questions:
Why do I have to specify this part public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension
with a constraint when I have already constrained the T in the declaration public interface IUIConcern<out T> where T : IUIConcernExtension
How can I have a property that holds a List<> of my IUIConcern<T> without knowing T other than knowing it will be derived from IUIConcernExtension?
Again, I realize this doesn't compile and is not correct, just looking to see how I can hold a list of generic items that may have many different type of IUIConcern<> elements.
Thank you!
You need to have a base interface, for instance:
public interface IUIConcern
{
string Name { get; }
}
public interface IUIConcern<out T> : IUIConcern where T : IUIConcernExtension
{
Func<T> Extern();
}
How you would define Concerns and Register would depend on how you treat T. Alternatively if you only deal with instances where you know T, you could use a Dictionary<Type, List<IUIConcern>> to hold anything, or potentially drop the base interface and just store using object depending on what you need in your controller code.
The problem is not located at the interface, but the problem is because of your generic implementation using static methods and properties.
The answer from Guvante was correct when saying that you need to define the IUIConcernExtension, but that is of course very logical, so im assuming you have just omitted that part since it does not matter for the issue you are facing.
The problem in the code is that you have created a class that has static methods and procedures, with the generic definition not laying at class level, but at methods level, because of this, the property that has and the Method cannot assume you are always with the same type!!
Lets say you call call :
Register<string>("something", UIConcern<string>)
but before that you have already called:
Register<Type>("something", UIConcern<Type>)
How could the compiler allows you to that?! So the answer is to define the generic type at class level, with this all properties and methods will be of same .
Also you need to use a private member for your list, since you doing everything static, the correct code should be:
interface IUIConcernExtension
{
string Name { get; }
}
public interface IUIConcern<out T> where T : IUIConcernExtension
{
Func<T> Extend();
}
public class UIConcern<T> where T : IUIConcernExtension
{
private static List<IUIConcern<T>> _Concerns = new List<IUIConcern<T>>();
public static void Register(string concernName, IUIConcern<T> uiConcern)
{
Concerns.Add(uiConcern);
}
public static List<IUIConcern<T>> Concerns
{
get { return _Concerns; }
set { _Concerns = value; }
}
}

Sealing an interface after implementing it

I am working on a small project and I came across that problem.
The project output is a library containing an interface. I would like to implement that interface and seal the functions in it like this if possible:
public interface ITest
{
void SomeMethod();
}
class A : ITest
{
public sealed override SomeMethod()
{
}
}
The idea is to have the interface available to everyone and have some specialized class that implements it. The exception is that I want to make sure that if someone create a specialized class of type A, he/she won't be able to change the method's behavior.
The problem is you can't put the "override" keyword in there since the method isn't declared as "virtual" in the interface. And you can't declare it as "virtual" in the interface since it's not allowed. And you can't remove the "override" keyword since it's needed by "sealed".
Any workaround or brainstorming idea would be welcome, but if someone can come up with a solution that includes an interface, I'd be really happy to learn it!
Thanks!
EDIT: Forget this question! Like Ani said, I forgot that by default method in C# are sealed. Seems like it's always good to go back to the basics once in a while...
I may have completely misunderstood the question, but if your intention is to seal the method in A, you can just do:
class A : ITest
{
public void SomeMethod() { ... }
}
Unlike Java, methods in C# are sealed by default. Subclasses of A won't be able to override the method since it hasn't been marked virtual.
On the other hand, if your intention is to mark the method 'almost sealed' in the interface, so that it forces upon an implementing class to immediately seal it, that isn't possible. It isn't (and shouldn't be) the business of the interface to dictate such details of implementation - an interface is meant to represent a specification.
Use an abstract base class with internal visibility. This base class is not visible outside of the library but allows you to seal the method and the class still implements the interface.
public interface ITest
{
void SomeMethod();
}
internal abstract class SuperA : ITest
{
public abstract void SomeMethod();
}
class A : SuperA
{
public sealed override void SomeMethod()
{
}
}
Your understanding of sealed keyword is incorrect. As a method modifier, sealed is used to prevent a virtual method(defined in the base class) to be override in the next generation of derived classes. For example:
class Base
{
public virtual void M() { }
}
class Derived : Base
{
public sealed override void M() { }
}
class A : Derived
{
public override void M() { } //compile error, M is sealed in Derived
}
Developers can always use new modifier to define a method with the same name in the derived class, that hides the one defined in the base class.
if someone create a specialized class
of type A, he/she won't be able to
change the method's behavior.
If "specialized class" means a class derived from A, the answer is: he can always hide the method in A, but he can't change the method's behavior.
Why not use an abstract class like below.
Haven't tested it but this should work?
public abstract class Test
{
public virtual void SomeMethod() {}
//OR
public abstract void SomeMethod();//MSDN says:
//an abstract method is implicitly virtual
}
class A : Test
{
public sealed override SomeMethod()
{
}
}
Methods in C# are sealed by default.. Here is a sample
class Program
{
static void Main(string[] args)
{
A obj = new A();
obj.SomeMethod();
b ss = new b();
ss.SomeMethod();
Console.ReadLine();
}
}
public interface ITest { void SomeMethod(); }
class A : ITest { public void SomeMethod() {
Console.WriteLine("SomeMethod Called from Class A object");
} }
class b : A
{
//public override void SomeMethod()
//{
// Console.WriteLine("Called from Class B Object");
//}
}

Using interfaces on abstract classes in C#

I'm learning C# coming from C++ and have run into a wall.
I have an abstract class AbstractWidget, an interface IDoesCoolThings, and a class which derives from AbstractWidget called RealWidget:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget : IDoesCoolThings
{
void IDoesCoolThings.DoCool()
{
Console.Write("I did something cool.");
}
}
public class RealWidget : AbstractWidget
{
}
When I instantiate a RealWidget object and call DoCool() on it, the compiler gives me an error saying
'RealWidget' does not contain a
definition for 'DoCool'
I can cast RealWidget object to an IDoesCoolThings and then the call will work, but that seems unnecessary and I also lose polymorphism (AbstractWidget.DoCool() will always be called even if i define RealWidget.DoCool()).
I imagine the solution is simple, but I've tried a variety of things and for the life of me can't figure this one out.
You're running into the issue because you used explicit interface implementation (EII). When a member is explicitly implemented, it can't be accessed through a class instance -- only through an instance of the interface. In your example, that's why you can't call DoCool() unless you cast your instance to IDoesCoolThings.
The solution is to make DoCool() public and remove the explicit interface implementation:
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool() // DoCool() is part of the abstract class implementation.
{
Console.Write("I did something cool.");
}
}
// ...
var rw = new RealWidget();
rw.DoCool(); // Works!
In general, you use EII in two cases:
You have a class that must implement two interfaces, each of which contains a member that has an identical name/signature to another member in the other interface.
You want to force clients not to depend on the implementation details of your class, but rather on the interface that's being implemented by your class. (This is considered a good practice by some.)
The way you implement the interface is explicit implement void IDoesCoolThings.DoCool(), if you choose implicit implement interface.
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
Then it will work.
Read this :
C# Interfaces. Implicit implementation versus Explicit implementation
Change your declaration to:
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
You should do it this way:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget
{
public void DoCool()
{
Console.WriteLine("I did something cool.");
}
}
public class Widget : AbstractWidget, IDoesCoolThings
{
}
Usage:
var widget = new Widget();
widget.DoCool();

Categories

Resources