We know that the Array class in c# is abstract.
But the static CreateInstance method of this class returns an object of the Array class.
How is it possible?
Description
No, you cant create an instance of an abstract class.
MSDN: Abstract classes are closely related to interfaces. They are classes that cannot be instantiated, and are frequently either partially implemented, or not at all implemented. One key difference between abstract classes and interfaces is that a class may implement an unlimited number of interfaces, but may inherit from only one abstract (or any other kind of) class. A class that is derived from an abstract class may still implement interfaces. Abstract classes are useful when creating components because they allow you specify an invariant level of functionality in some methods, but leave the implementation of other methods until a specific implementation of that class is needed. They also version well, because if additional functionality is needed in derived classes, it can be added to the base class without breaking code.
More Information
MSDN - Abstract Classes
It's a static factory method that returns an instance of array. this example creates an array of length 10 for integer value types.
System.Array myIntArray = Array.CreateInstance(typeof(int),10);
This should give you some more detail http://msdn.microsoft.com/en-us/library/zb3cfh7k.aspx
The various overloads of the method Array.CreateInstance() are typed as returning Array, which indeed is an abstract class. But the type of the object they return is not directly Array, it's some type that inherits from Array (what type exactly depends on the overload used and the parameters you pass in).
For example:
Array a = Array.CreateInstance(typeof(int), 10); //create some array
Type type = a.GetType(); // type is int[], which is not abstract
Type baseType = type.BaseType; // baseType is Array
Basically, it's the same principle like the following factory method:
abstract class Animal
{
public static Animal CreateInstance(AnimalType animalType)
{
if (animalType == AnimalType.Cat)
return new Cat();
if (animalType == AnimalType.Dog)
return new Dog();
// etc.
}
}
Here, Animal is an abstract base type, Cat and Dog are concrete types that inherit from Animal and animalType tells us which type should the method return.
Now, arrays are treated specially in several ways in .Net (for example, there are IL instructions specifically for dealing with arrays). But they are not an exception in the type system (except, maybe for array covariance).
Array seems to be a special case of abstract class. From what I've read in Documentation I'd suggest that Array creation and functions are somehow handled internally in .NET Framework code - most probably extensively using native code for better performance results. I think that's why this class have been made abstract.
I'd be glad if someone more knowledgable of .NET Framework internals can improve my answer.
I think the best way to relate to this situation is by considering a method that returns you instance of an interface!!!
Well, you know that we can not create instance of an interface, but internally a method may know about a class implementing that interface and return instance of that class.
namespace ConsoleApplication1
{
public class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("Draw a Circle");
}
}
public abstract class Shape
{
public abstract void Draw();
}
}
You can do like this
class Program
{
static void Main(string[] args)
{
Shape v;
v = new Circle();
v.Draw();
}
}
Related
I want to create a class library, that contains an interface that objects can derive of, lets say ISaveableObject.
Now, this interface should implement the following functionality:
Objects that derive off this interface should have a method ToSaveableObject (similar to the System.Object.ToString() method).
And it should contain a specific constructor, which takes an array of objects as its parameter.
The connection between these two should be that the ToSaveableObject method returns a string that takes all the properties that are needed for the object[] and convert it into a readable string and return it.
Am I going in the correct direction by wanting to use an interface or is an abstract class better suited for this case?
Sadly, interfaces cannot implement constructors, so is there another way to accomplish my goal?
Use an abstract base class to form your contract for derived classes. What you want is more of an implementation detail which is more than what an interface can provide.
abstract base class could look like this
public abstract class SaveableObject {
protected object[] parameters = new object[0];
protected SaveableObjectBase(object[] objects) {
this.parameters = objects;
}
public abstract string ToSaveableObject();
}
So now derived classes have to implement the ToSaveableObject() method and will have access to the objects passed in the constructor to generate the string.
If the construction algorithm for the ToSaveableObject method is the same for all derived types then you should just implement that method in the base abstract class so that all derived classes will have the functionality already built in.
I have two sequences of objects 'A' and 'B'. Comparing the sequences should produce a third sequence 'C' of elements that indicate whether:
the objects were "deleted" from 'A' or
"inserted" from 'B'.
All remaining elements are considered as "matched".
What I would like to do:
Declare Inserted<T>, Deleted<T>, and Matched<T> generic classes that inherit all their properties from the T base class. The generic class must be able to instantiate itself from the object it inherits.
The code:
public interface IInstantiable<T>
{
void CopyFrom(T o);
}
[Serializable]
public class Inserted<T> : T
where T : IInstantiable<T>
{
public Inserted() { }
public Inserted(T t)
{
this.CopyFrom(t);
}
}
The error:
'MyNamespace.Inserted<T>' does not contain a definition for 'CopyFrom' and no
extension method 'CopyFrom' accepting a first argument of type 'MyNamespace.Inserted<T>'
could be found (are you missing a using directive or an assembly reference?)
Further discussion:
I define my own IInstantiable interface to enforce the existence of a CopyFrom method. I cannot use the standard ICloneable interface, because it only defines a method that copies the object to a new instance, whereas I need the object to copy its members in the constructor.
The error goes away if the generic defines its own implementation of the CopyFrom method; however, this does not achieve the desired goal of specializing the CopyFrom method to handle the specific needs of the base class. Only the base class could know what properties should be copied. (Or am I missing something?)
Note: The final object should have the same public members as its base class, as the object should be capable of serialization.
Is this possible in .NET?
The answer:
What I am attempting to do is impossible, simply because the generic class cannot be an extension of the template base class. Visual Studio complains "Cannot derive from 'T' because it is a type parameter." (I hadn't noticed this error yet because I had not implemented the CopyFrom method in the generic class yet.)
If I were to change the interface into a class and supply a stub implementation in that class, I could inherit from it as suggested below; however, this introduces a new base class into my inheritance hierarchy.
public class IInstantiable<T>
{
public virtual void CopyFrom(T o) { }
}
[Serializable]
public class Inserted<T> : IInstantiable<T>
where T : IInstantiable<T>
{
public Inserted() { }
public Inserted(T t)
{
base.CopyFrom(t);
}
}
Unfortunately, I cannot use this new base class in its templatized form because I must introduce it at the root of my inheritance hierarchy. It works only if I remove the template and make it as generic as possible.
public class IInstantiable
{
public virtual void CopyFrom(Object o) { }
}
However, this still does not make my Inserted<T> generic look like the object it is initialized from, and since I cannot inherit from the same type as the type parameter, it does not suit my initial purpose.
Moving away from "fancy generics" based on the type system to more (ahem) generic annotated structures might prove to be the best solution; however, the default behavior of my selected serialization approach (XmlSerialization) does not have the automatic support that would make this configuration a viable solution. Generics will not work; use hard-coded class definitions instead.
This is indirectly what you're trying to declare in your code above.
[Serializable]
public class Inserted<T> : IInstantiable<T>
where T : IInstantiable<T>
{
public Inserted() { }
public Inserted(T t)
{
this.CopyFrom(t);
}
}
Does this make sense?
.NET doesn't allow you to inherit from a generic parameter. How could it? Generics are evaluated at runtime but it needs to know what type your class is at compile time.
If I understand correctly, you want to annotate a sequence of objects with the notion of what their state is (inserted, deleted, or matched).
You don't really need fancy generics for this; what's wrong with:
enum ChangeState { Inserted, Deleted, Matched }
struct<T> Annotated {
public T Obj;
public ChangeState;
}
You can mark this for serialization however you want (the Annotated object can serialize just fine without the same properties/fields).
Though you can encode more information in the type system, it's unclear to me what the benefit would be here. Are you sure you want to do that?
I want to know the reason behind the design of restricting Abstract Methods in Non Abstract Class (in C#).
I understand that the class instance won't have the definition and thus they wont be callable, but when static methods are defined,they are excluded from the instance too. Why abstract methods are not handled that way, any specific reason for the same?
They could be allowed in concrete class and the deriving class can be forced to implement methods, basically that is what, is done in case of abstract methods in an abstract class.
First, I think that what you're asking doesn't logically make sense. If you have an abstract method, it basically means that the method is unfinished (as #ChrisSinclair pointed out). But that also means the whole class is unfinished, so it also has to be abstract.
Or another way to put it: if you had an abstract method on a class that wasn't abstract, that would mean you had a method that cannot be called. But that means the method is not useful, you could remove it and it would all work the same.
Now, I'll try to be more concrete by using an example: imagine the following code:
Animal[] zoo = new Animal[] { new Monkey(), new Fish(), new Animal() };
foreach (Animal animal in zoo)
animal.MakeSound();
Here, Animal is the non-abstract base class (which is why I can put it directly into the array), Monkey and Fish are derived from Animal and MakeSound() is the abstract method. What should this code do? You didn't state that clearly, but I can imagine few options:
You can't call MakeSound() on a variable typed as Animal, you can call it only using a variable typed as one of the derived classes, so this is a compile error.
This is not a good solution, because the whole point of abstract is to be able to treat instances of derived classes as the base class, and still get behaviour that's specific to the derived class. If you want this, just put a normal (no abstract, virtual or override) method into each derived class and don't do anything with the base class.
You can't call MakeSound() on an object whose runtime type is actually Animal, so this is a runtime error (an exception).
This is also not a good solution. C# is a statically typed language and so it tries to catch errors like “you can't call this method” at compile time (with obvious exceptions like reflection and dynamic), so making this into a runtime error wouldn't fit with the rest of the language. Besides, you can do this easily by creating a virtual method in the base class that throws an exception.
To sum up, you want something that doesn't make much sense, and smells of bad design (a base class that behaves differently than its derived classes) and can be worked around quite easily. These are all signs of a feature that should not be implemented.
So, you want to allow
class C { abstract void M(); }
to compile. Suppose it did. What do you then want to happen when someone does
new C().M();
? You want an execution-time error? Well, in general C# prefers compile-time errors to execution-time errors. If you don't like that philosophy, there are other languages available...
I think you've answered your own question, an abstract method isn't defined initially. Therefore the class cannot be instanciated. You're saying it should ignore it, but by definition when adding an abstract method you're saying "every class created from this must implement this {abstract method}" hence the class where you define the abstract class must also be abstract because the abstract method is still undefined at that point.
The abstract class may contain abstract member. There is the only method declaration if any method has an abstract keyword we can't implement in the same class. So the abstract class is incompleted. That is why the object is not created for an abstract class.
Non-abstract class can't contain abstract member.
Example:
namespace InterviewPreparation
{
public abstract class baseclass
{
public abstract void method1(); //abstract method
public abstract void method2(); //abstract method
public void method3() { } //Non- abstract method----->It is necessary to implement here.
}
class childclass : baseclass
{
public override void method1() { }
public override void method2() { }
}
public class Program //Non Abstract Class
{
public static void Main()
{
baseclass b = new childclass(); //create instance
b.method1();
b.method2();
b.method3();
}
}
}
You can achieve what you want using "virtual" methods but using virtual methods can lead to more runtime business logic errors as a developer is not "forced" to implement the logic in the child class.
I think there's a valid point here. An abstract method is the perfect solution as it would "enforce" the requirement of defining the method body in children.
I have come across many many situations where the parent class had to (or it would be more efficient to) implement some logic but "Only" children could implement rest of the logic"
So if the opportunity was there I would happily mix abstract methods with complete methods.
#AakashM, I appreciate C# prefers compile time errors. So do I. And so does anybody. This is about thinking out-of-the-box.
And supporting this will not affect that.
Let's think out of the box here, rather than saying "hurrah" to big boy decisions.
C# compiler can detect and deny someone of using an abstract class directly because it uses the "abstract" keyword.
C# also knows to force any child class to implement any abstract methods. How? because of the use of the "abstract" keyword.
This is pretty simple to understand to anyone who has studied the internals of a programming language.
So, why can't C# detect an "abstract" keyword next to a method in a normal class and handle it at the COMPILE TIME.
The reason is it takes "reworking" and the effort is not worth supporting the small demand.
Specially in an industry that lacks people who think out of the boxes that big boys have given them.
It's still not clear why you would want that, but an alternative approach could be to force derived classes to provide a delegate instance. Something like this
class MyConcreteClass
{
readonly Func<int, DateTime, string> methodImpl;
// constructor requires a delegate instance
public MyConcreteClass(Func<int, DateTime, string> methodImpl)
{
if (methodImpl == null)
throw new ArgumentNullException();
this.methodImpl = methodImpl;
}
...
}
(The signature string MethodImpl(int, DateTime) is just an example, of course.)
Otherwise, I can recommend the other answers to explain why your wish probably isn't something which would make the world better.
So the answers above are correct: having abstract methods makes the class inherently abstract. If you cannot instance part of a class, then you cannot instance the class itself. However, the answers above didn't really discuss your options here.
First, this is mainly an issue for public static methods. If the methods aren't intended to be public, then you could have protected non-abstract methods, which are allowed in an abstract class declaration. So, you could just move these static methods to a separate static class without much issue.
As an alternative, you could keep those methods in the class, but then instead of having abstract methods, declare an interface. Essentially, you have a multiple-inheritance problem as you want the derived class to inherit from two conceptually different objects: a non-abstract parent with public static members, and an abstract parent with abstract methods. Unlike some other frameworks, C# does permit multiple inheritance. Instead, C# offers a formal interface declaration that is intended to fill this purpose. Moreover, the whole point of abstract methods, really, is just to impose a certain conceptual interface.
I have a scenario very similar to what the OP is trying to achieve. In my case the method that I want to make abstract would be a protected method and would only be known to the base class. So the "new C().M();" does not apply because the method in question is not public. I want to be able to instantiate and call public methods on the base class (therefore it needs to be non-abstract), but I need these public methods to call a protected implementation of the protected method in the child class and have no default implementation in the parent. In a manner of speaking, I need to force descendants to override the method. I don't know what the child class is at compile time due to dependency injection.
My solution was to follow the rules and use a concrete base class and a virtual protected method. For the default implementation, though, I throw a NotImplementedException with the error "The implementation for method name must be provided in the implementation of the child class."
protected virtual void MyProtectedMethod()
{
throw new NotImplementedException("The implementation for MyProtectedMethod must be provided in the implementation of the child class.");
}
In this way a default implementation can never be used and implementers of descendant implementations will quickly see that they missed an important step.
I would like to know the difference between two conventions:
Creating an abstract base class with an abstract method
which will be implemented later on the derived classes.
Creating an abstract base class without abstract methods
but adding the relevant method later on the level of the derived classes.
What is the difference?
Much like interfaces, abstract classes are designed to express a set of known operations for your types. Unlike interfaces however, abstract classes allow you to implement common/shared functionality that may be used by any derived type. E.g.:
public abstract class LoggerBase
{
public abstract void Write(object item);
protected virtual object FormatObject(object item)
{
return item;
}
}
In this really basic example above, I've essentially done two things:
Defined a contract that my derived types will conform to.
Provides some default functionality that could be overriden if required.
Given that I know that any derived type of LoggerBase will have a Write method, I can call that. The equivalent of the above as an interface could be:
public interface ILogger
{
void Write(object item);
}
As an abstract class, I can provide an additional service FormatObject which can optionally be overriden, say if I was writing a ConsoleLogger, e.g.:
public class ConsoleLogger : LoggerBase
{
public override void Write(object item)
{
Console.WriteLine(FormatObject(item));
}
}
By marking the FormatObject method as virtual, it means I can provide a shared implementation. I can also override it:
public class ConsoleLogger : LoggerBase
{
public override void Write(object item)
{
Console.WriteLine(FormatObject(item));
}
protected override object FormatObject(object item)
{
return item.ToString().ToUpper();
}
}
So, the key parts are:
abstract classes must be inherited.
abstract methods must be implemented in derived types.
virtual methods can be overriden in derived types.
In the second scenario, because you wouldn't be adding the functionality to the abstract base class, you couldn't call that method when dealing with an instance of the base class directly. E.g., if I implemented ConsoleLogger.WriteSomethingElse, I couldn't call it from LoggerBase.WriteSomethingElse.
The idea of putting abstract methods in a base class and then implementing them in subclasses is that you can then use the parent type instead of any specific subclass. For example say you want to sort an array. You can define the base class to be something like
abstract class Sorter {
public abstract Array sort(Array arr);
}
Then you can implement various algorithms such as quicksort, mergesort, heapsort in subclasses.
class QuickSorter {
public Array sort(Array arr) { ... }
}
class MergeSorter {
public Array sort(Array arr) { ... }
}
You create a sorting object by choosing an algorithm,
Sorter sorter = QuickSorter();
Now you can pass sorter around, without exposing the fact that under the hood it's a quicksort. To sort an array you say
Array sortedArray = sorter.sort(someArray);
In this way the details of the implementation (which algorithm you use) are decoupled from the interface to the object (the fact that it sorts an array).
One concrete advantage is that if at some point you want a different sorting algorithm then you can change QuickSort() to say MergeSort in this single line, without having to change it anywhere else. If you don't include a sort() method in the parent, you have to downcast to QuickSorter whenever calling sort(), and then changing the algorithm will be more difficult.
In the case 1) you can access those methods from the abstract base type without knowing the exact type (abstract methods are virtual methods).
The point of the abstract classes is usually to define some contract on the base class which is then implemented by the dervied classes (and in this context it is important to recognize that interfaces are sort of "pure abstract classes").
Uhm, well, the difference is that the base class would know about the former, and not about the latter.
In other words, with an abstract method in the base class, you can write code in other methods in the base class that call that abstract method.
Obviously, if the base class doesn't have those methods... you can't call them...
An abstract function can have no functionality. You're basically saying, any child class MUST give their own version of this method, however it's too general to even try to implement in the parent class. A virtual function, is basically saying look, here's the functionality that may or may not be good enough for the child class. So if it is good enough, use this method, if not, then override me, and provide your own functionality...
And of course, if you override a virtual method, you can always refer to the parent method by calling base.myVirtualMethod()
Okay, when you see a method like this:
A.Foo();
What you really have (behind the scenes) is a signature like this.
Foo(A x);
And when you call A.Foo() you're really calling Foo(this) where this is a reference to an object of type A.
Now, sometimes you'd like to have Foo(A|B|C|D...) where Foo is a method that can take either a type A, or B, or C, or D. But you don't want to worry about what type you're passing, you just want it to do something different based on the type that was passed in. Abstract methods let you do that, that's their only purpose.
I have just seen on the comment to a blog post:
Base abstract generic class is a bad
choice in most situations
Is this true, if not why?
What insight(s) leads to this statement?
I agree, because anything that inherits an abstract generic class will not be polymorphic with the base class. That is, if you have
abstract class myBase<T>
then you create
class myThing: myBase<thing>
class myOtherThing: myBase<otherThing>
you can't create methods that work against myThing and myOtherThing since they do not share an ancestor. There's no point in the base class being abstract, really, it might as well just be a class.
But if you have a base class
abstract class myBase
class myBase<T>: myBase
as is a common pattern for generic classes (like IEnumerable - using interfaces), then they all share myBase.
(edit) I just read the actual blog post - and actually, the comment is not really valid in that situation. The "abstract generic base class" he's referring to, Range<T> inherits IEnumerable<T> which inherits non-generic interface IEnumerable. So it's not really an "abstract generic base class." But generally I think it's true.
"Most situations" is outrightly vague. A generic abstract class (or interface) is a bad idea if the only common ancestor between descendants of such class is System.Object (as noted by other commenters of this question).
Otherwise (as in, if you do have a meaningful common ancestor), it's a good idea if you want to "rename" or "specialize" members. Consider this example:
// Meaningful common ancestor for the working classes.
interface IWorker
{
object DoWork();
}
// Generic abstract base class for working classes implementations.
abstract WorkerImpl<TResult> : IWorker
{
public abstract TResult DoWork();
object IWorker.DoWork()
{
return DoWork(); // calls TResult DoWork();
}
}
// Concrete working class, specialized to deal with decimals.
class ComputationWorker : WorkerImpl<decimal>
{
override decimal DoWork()
{
decimal res;
// Do lengthy stuff...
return res;
}
}
In this example, DoWork() was redefined in the abstract class, becoming concrete and specialized in ComputationWorker.
One problem with abstract generic base class is that you can't type decorate :
public abstract class Activity<TEntity>
{
public Activity() { }
protected virtual object Implementation { ... }
}
public abstract class CompensableActivity<TEntity,TCompensation> : Activity<TEntity>
where TCompensation : Activity<T>, new()
{
public CompensableActivity() { }
protected override object Implementation
{
get { new Wrapper(base.Implementation, Compensation); }
}
private Activity<TEntity> Compensation
{
get
{
var compensation = new TCompensation();
if(compensation is CompensableActivity<TEntity,Activity<TEntity>)
{
// Activity<TEntity> "does not meet new() constraint" !
var compensable = comp as CompensableActivity<TEntity, Activity<TEntity>>;
var implement = compensable.Implementation as Wrapper;
return implement.NormalActivity;
}
else { return compensation; }
}
}
}
Kragen makes a good point. Anything that is less than 50% of your code is "the wrong choice in the majority of situations".
However, even though nowhere near 50% of your classes should be generic abstract base classes, it also isn't less of a good thing than any other language feature.
For example, BindingList<T> could be considered an abstract generic base class. It's a generic container, and sorting requires you to derive from it and override ApplySortCore.
KeyedCollection<TKey, TItem> doesn't just act like an abstract generic base class, it is one. To use it you MUST derive from it and implement GetKeyForItem.
I disagree with the crowd here. In some cases an abstract generic class is the best design.
A good example in .NET can be found in System.Collections.ObjectModel where the KeyedCollection allows you to override and implement a typed serializable dictionary collection easily!
I elided most of the code but this is the principle:
public class NameCollection : System.Collections.ObjectModel.KeyedCollection<string, INamedObj>
{
protected override string GetKeyForItem(INamedObj item)
{
return item.Name;
}
}
Well, statistically speaking if someone asked me "should I make this class an abstract generic class?", the answer would almost certainly be no - in 3 years of .Net development I think I can count the number of abstract classes that I've written that had generic type parameters on one hand.
Other than that I can't see any particular reason for an abstract generic class to be considered a Bad Thing - its just not that common.
There are situations where an abstract base class is useful thing.
We have several .net applications that use different database engines. Several sql server, a couple of mysql and a bunch of oracle apps.
We have a generic common database object which is based on an abstract class that is a factory that returns the proper database object in a factory setting based on the type of database.
That way if I am starting a new application, all I have to do is load this database object, pass in the type, pass in the connection string, and bam... i'm set...
I guess what I'm trying to say is it all depends on the context and how its actually used.