Instancing an abstract class? - c#

public abstract class T
{
public abstract IEnumerable<T> MakeOneMove();
public IEnumerable<T> MakeOneMove(string evt)
{
List<T> returnList = new List<T>();
IEnumerable<T> steps = MakeOneMove();
foreach (T step in steps)
{
if (step.Event == evt)
{
returnList.Add(step);
}
}
return returnList;
}
and elsewhere the class is used like this:
T currentImpl = pendingImpl.Pop();
IEnumerable<T> nextImpl = currentImpl.MakeOneMove();
foreach (ConfigurationBase next in nextImpl){
}
I am confused about two things. It seems like class T is being instanced , but class T is an abstract class. I thought this wasn't possible. I thought only non-abstract subclasses of the abstract class could be instanced. Also, in the class, makeonemove() is called, but isn't the version with no arguments not overridden and therefore not defined? it seems to me like this code shouldn't compile, yet it does.

I am confused about two things. It seems like class T is being
instanced , but class T is an abstract class. I thought this wasn't
possible. I thought only the subclass could be instanced.
abstract class T is not being instantiated, rather it is just a pointer to a concrete implementation of the abstract class.
Also, in the
class, makeonemove() is called, but isn't the version with no
arguments not overridden? it seems to me like this code shouldn't
compile, yet it does.
This is one of the benefits of using an Abstract Class. It allows you to provide a "base" implementation of its members that can be overridden in derived classes.

No, The class T is abstract. In the method call T currentImpl = pendingImpl.Pop(); the T there just means that the object returned will be a type which derives from T, it effectively establishes (Declares) the type of the variable named currentImpl, not the type of the object itself.
The actual type of the object being instantiated will be whatever type pendingImpl.Pop() creates. It looks like Pop() is what is called a factory method. You would have to look at how it is implemented to see exactly what type is instantiates and returns.

No, T just means that the class has to be convertible to T (ie it iherits from it and can be cast as T).
I suggest checking here to read up on inheritance:
http://www.csharp-station.com/Tutorial/CSharp/lesson08
And here to read about casting:
http://csharp-station.com/Tutorial/CSharp/Lesson22
Essentially if a class inherits another, it can be cast into an instance of the class and is thus treated as that class for the cast.
So say I made a Class H that inherited from T, then cast it to T, for the duration of that cast, H would essentially be disguised as T and you could only access the elements it inherits from T. So say I gave H a function called 'MakeTwoMoves', then made an instance of H called 'hi' (eg H hi = new H();) I could call MakeOneMove and MakeTwoMoves. Once it is cast to T however (eg (T)H) you MakeTwoMoves is no longer accessible because it's not declared in T, it's something unique to H.
What this means for your code however is that pendingImpl most likely would contain an array of instances of classes that have inherited from T (like the H in my example). They are then cast inside the pop method (or possibly earlier, ie before being put in the internal array) and come out as T, so each instance could be a completely different class but the only thing you know about them is that they inherit from T.
I hope that cleared things up a bit, T isn't the most intuitive name to work with.

Related

Understanding inherited and base items in a list

This is a question that might perhaps be foolish, but I can't seem to reason my way around it so I have come here for some thoughts. It's about inheritance and lists.
Alright, so I have two classes: TestClass and DerivedTestClass. DerivedTestClass is derived from TestClass. Both classes have a method called 'Method1'.
These are both very simple methods. They just have a message box saying what method is being accessed. In fact, let me write the code just to remove ambiguity:
public void Method1(String typeName)
{
MessageBox.Show("Base method 1 + Type: "+typeName);
}
This is for the base class (TestClass).
public void Method1(String typeName)
{
MessageBox.Show("Derived method 1 + Type: "+typeName);
}
This is for the derived class (DerivedTestClass).
Next I created an instance of both of these and called the Method1 for each. And it's exactly as you'd expect. When I called it for the base class I for the first message box, and when I called the derived class I got the second one.
No mysteries so far, but now we get to the part where my understanding seems to be lacking.
I create a List into which I add both instances I have created: the instance of the base class and the instance of the derived class. Then I created a foreach loop which went through each item in the list and called Method1, as follows:
foreach (var tc in listT)
{
tc.Method1(tc.GetType().Name);
}
In both cases the base method is called. Now in one respect I get that as the list itself is the type of the base class. The problem is if I look at the types. If I ask the first item in the list what its type is, it will say TestClass. If I ask the second item in the list what its type is, it will say DerivedBaseClass.
Now one can solve this by casting each item within the list to its own type. But it can require a long list of if statements based on how many derived types you have. Also, and I suppose this is the heart of the problem, I'm just confused about ever having to cast something to that which it already is. If the item is a DerivedBaseClass (as evidenced by the GetType()), it seems odd that I have to cast that to DerivedBaseClass. Can I rely on GetType in these situations? Should it come with an asterisk that says 'well the memory declared is only enough for the base class, and while this is a derived class, it's currently in the form of a base class'?
So you could say I'm a bit confused and looking for clarification.
Two things:
You aren't overriding Method1, you are hiding it in the derived class so you can consider these methods as completely different things entirely.
Your list only contains references to the base type, and as such will only call the methods it exposes.
To fix this, change your types to something like this, note the virtual base method and the override in the derived class:
public class BaseType
{
public virtual void Method1(String typeName)
//^^^^^^^ This
{
MessageBox.Show("Base method 1 + Type: "+typeName);
}
}
public class DerivedType : BaseType
{
public override void Method1(String typeName)
//^^^^^^^^ And this
{
MessageBox.Show("Derived method 1 + Type: "+typeName);
}
}

Call static method from generic abstract class without specifying a type

I have an abstract class like this:
public abstract class BaseCamera<TCamera> : ICamera where TCamera : ManagedCameraBase
{
public static uint GetNumberOfCameras()
{
using (var bus = new ManagedBusManager())
{
bus.RescanBus();
return bus.GetNumOfCameras();
}
}
}
And want to call it like this:
BaseCamera.GetNumberOfCameras()
It makes sense to me, because since this is an abstract class, only the concrete children classes must choose a TCamera, and the base class wants to get the number of all cameras, no matter they type.
However, the compiler does not approve:
Using the Generic type 'BaseCamera' requires 1 type
arguments.
Is there some way around it or do I need to create a new class just for this?
I think it is worth pointing out that ManagedCameraBase is a class from an external API I'm wrapping. Therefore, I do not want to include it in any of my calls for BaseCamera and that is why I'm trying to avoid specifying a type.
because since this is an abstract class, only the concrete children classes must choose a TCamera
That's not how generics work. This has nothing at all to do with the class being abstract. If the class was generic and not abstract you would still need to specify a generic argument in order to call a static method of the class. On top of that, there's nothing to say that a child class can't also be generic. Yours may happen to not be, but there's nothing requiring that to be the case.
Now, in your particular case, the GetNumberOfCameras method doesn't use the generic argument (T) at all, so it doesn't matter what generic argument you provide, you can put in whatever you want and it'll work just fine. Of course, because of that, it's a sign that this method probably doesn't belong in this class; it should probably be in another class that this class also uses.
Here's the problem. The static method GetNumberOfCameras belongs to the class that contains it, but a generic class actually gets compiled into separate classes for each type. So, for example if you had this:
public class Foo<T>
{
static int foo = 0;
public static void IncrementFoo()
{
foo++;
}
public static int GetFoo()
{
return foo;
}
}
And then you did this:
Foo<string>.IncrementFoo();
Console.WriteLine(Foo<string>.GetFoo());
Console.WriteLine(Foo<int>.GetFoo());
You will see that the first call to GetFoo will return one, but the second will return zero. Foo<string>.GetFoo() and Foo<int>.GetFoo() are two separate static method that belong to two different classes (and access two different fields). So that's why you need a type. Otherwise the compiler won't know which static method of which class to call.
What you need is a non-generic base class for your generic class to inherit from. So if you do this:
public class Foo<T> : Foo
{
}
public class Foo
{
static int foo = 0;
public static void IncrementFoo()
{
foo++;
}
public static int GetFoo()
{
return foo;
}
}
Then this:
Foo<string>.IncrementFoo();
Console.WriteLine(Foo<string>.GetFoo());
Console.WriteLine(Foo<int>.GetFoo());
Will give you what you might have expected at first. In other words, both calls to GetFoo will return the same result. And, of course, you don't actually need the type argument anymore and can just do:
Foo.IncrementFoo();
Or course, the alternative is to just move your static methods into an entirely different class if there's no reason why it should be part of BaseCamera
Well, there are a couple of things here you need to understand better.
First of all, I see a problem with your design. The method you are attempting to stick into this class really has nothing to do with the generic nature of it. In fact, you are instantiating another class to do the job so it really does not belong here at all.
If it actually had something to do with an object that inherits from ManagedCameraBase, the method would probably not need to be static but rather an instance method. You can then decide on the accessor (public/private) based on usage.
Finally, you need to understand what Generics actually do under the covers. When you use the generic base with a particular type, an underlying specialized type is created for you behind the scenes by the compiler. If you were to use the static method, the compiler would need to know the type you are targeting in order to create the static instance that will serve your call. Because of this, if you call the static method, you must pass a type and you will end up with as many static instances as the types you use to call it (the types must derive from ManagedCameraBase, of course).
As you can see, you should either move that method out to some helper class or something of the sort, or make it a non-static, instance method.

C#: Force constructor signature using abstract class?

I've been searching for a while on this because I'm naturally forgetful and I thought it would be nice to build something (an abstract class, interface, etc.?) that would force me to implement certain bits of code in a class I was writing.
In particular, I would like to force a new class to always have a constructor that takes a single parameter typed as itself in order to make duplication of the object easier. I've seen articles/questions elsewhere that talk about this, but I'm not sure this particular question has been asked (at least that I can find) or I'm simply not understanding enough of the other articles/questions to realize it. My apologies in advance.
I'm not interested in having a constructor in an abstract class, interface, etc. actually do anything. I'm merely interested in defining the requirement for a constructor signature in a derived class.
My ideal class would look like this:
public class GoodClass
{
public GoodClass(GoodClass goodClass)
{
// copy components of goodClass to this instance
}
}
So, I first began researching interfaces and also started reading up on abstract classes. I was thinking something like the code below would work, but alas I get errors. Is what I'm trying to do even possible? Is there any other way I could accomplish my goal without putting a sticky note on my monitor? :)
abstract class SelfConstructor
{
abstract public SelfConstructor(SelfConstructor) { }
}
class NewClass : SelfConstructor
{
//Required by SelfConstructor:
public NewClass(NewClass newClass)
{
// copy components of newClass to this instance
}
}
You could write a ReSharper plugin that recognises this case and highlights the class if it doesn't have a "copy constructor". This would be a daemon stage that would process the file as it's being edited, and add highlights. You can look through the abstract syntax tree of the file, look for all instances of IConstructorDeclaration, and then get the constructor's parameters from the ParameterDeclarations property. You can check that there is a constructor that only has one parameter, and that parameter is the same type as the class it's declared in.
You can compare the types by getting the constructor's parameter's TypeUsage and trying to downcast to IUserTypeUsage. You can then use ScalarTypeName.Reference.Resolve() to get an instance of IDeclaredElement. Compare this against the class's IClassDeclaration.DeclaredElement to see if they're the same instance.
In C++, what you are talking about is a copy constructor, you actually get one by default!
C# doesn't have that concept (though of course you can define one); however, it is easier (and preferred) to simply implement ICloneable (MSDN), which requires you to implement the Clone method, that does the same thing.
Instead of:
object myObj = new CloneableObject(otherObj);
You write:
object myObj = otherObj.Clone();
The other thing you could do is force a constructor signature by not having a default:
public class BaseClass
{
//No abstract constructors!
public BaseClass(BaseClass copy)
{
}
}
Now when you derive, you have to use that overload in the constructor. Nothing will force the derived signature, but at least you have to explicitly use it:
public class DerivedClass : BaseClass
{
public DerivedClass() : base(this)
{
}
}
The above example clearly shows that it doesn't "force" you to have a copy constructor, but like a sticky note, would serve as a good reminder.
I would definitely go the interface route, as that is what is there for (and you can use an abstract implementation!).
Note that you can take advantage of Object.MemberwiseClone if you want a shallow copy for free. All objects get this, no interface required.

c# generics on a method with the constraint that the type must be of "this" type

I have a C# class hierarchy with a common base type and two derived types. I want to declare an abstract method on the base class something like this :
public abstract IEnumerable<T> GetSiblings<T>() where T : MyBaseClass
... and I want this method to be implemented in the derived classes such that T is the type of that derived type, for each of the derived types, ie, in derived class A:
public override IEnumerable<A> GetSiblings<A>() { ... }
... and in derived class B ...
public override IEnumerable<B> GetSiblings<B>() { ... }
Put another way, each derived class must implement the method so that it returns an IEnumerable of items of the same type. Is there any way to implement this in C# ?
Well, you can hardly call a method generic if it only accepts a parameter of a single type, and your method signatures will have different return types which isn't allowed. Why don't you define an interface for all of these classes and simply return an IEnumerable<IMyClass>?
You can't do this because the return types are different. Simple as that. The reason is if you create an instance of A and stuff it into your base class(cast it) then the return type will be wrong.
You might be able to to use new instead but that might break your hierarchy.
This is not supported by the type system. It's a common enough problem, represented often as
class Animal<T> where T : Animal<T> { }
class Cat : Animal<Cat> { } // what you desire
class Dog : Animal<Cat> { } // what is possible yet not desired
But not a problem that has as yet been acted upon by the appropriate parties (be it the framework providers or C# team, not sure who).
Until it passes the critical "worth it" test as determined by costs (and opportunity costs) versus benefits, you'll have to work around it.
I found the solution. Apparently in C# 4.0, generic parameter types can be covariant, so what I've posted above will work. C# 3.5 or lower, and it doesn't work. Took a lot of Googling.

How to prevent inheritance for some methods?

How can I prevent inheritance of some methods or properties in derived classes?!
public class BaseClass : Collection
{
//Some operations...
//Should not let derived classes inherit 'Add' method.
}
public class DerivedClass : BaseClass
{
public void DoSomething(int Item)
{
this.Add(Item); // Error: No such method should exist...
}
}
The pattern you want is composition ("Has-a"), not inheritance ("Is-a"). BaseClass should contain a collection, not inherit from collection. BaseClass can then selectively choose what methods or properties to expose on its interface. Most of those may just be passthroughs that call the equivalent methods on the internal collection.
Marking things private in the child classes won't work, because anyone with a base type variable (Collection x = new DerivedClass()) will still be able to access the "hidden" members through the base type.
If "Is-a" vs "Has-a" doesn't click for you, think of it in terms of parents vs friends. You can't choose your parents and can't remove them from your DNA, but you can choose who you associate with.
You can't, in this instance inheritance is the wrong tool for the job. Your class needs to have the collection as a private member, then you can expose as much or as little of it as you wish.
Trying to hide a public member of a class in a derived class is generally a bad thing(*). Trying to hide it as a means of ensuring it won't be called is even worse, and generally won't work anyhow.
There isn't any standardized idiomatic means I know of to prevent a parent class' protected member from being accessed in a sub-derived type, but declaring a new public useless member of a clearly-useless kind would be one approach. The simplest such thing would be an empty class. For example, if class Foo declares an empty public class called MemberwiseClone, derivatives of Foo will be unable to call MemberwiseClone--probably a good thing if MemberwiseClone would break the invariants of class Foo.
(*) The only situation where it is appropriate is when a public method of a derived class returns a more specialized type than the corresponding method in the base class (e.g. a CarFactory.Produce() method may return a Car, while the FordExplorerFactory.Produce() method may return a FordExplorer (which derives from car). Someone who calls Produce() on what they think is a CarFactory (but happens to be a FordExplorerFactory) will get a Car (which happens to be a FordExplorer), but someone who calls Produce() on what is known at compile time to be a FordExplorerFactory will get a result that's known at compile time to be a FordExplorer.

Categories

Resources