Reputation: 4929
I have a library which contains a class. This class is meant to be extended. It will connect to a database and generate entries of the class which extends it. Now I want to return an array of the type of the extending class. How can I do this ? For example :
public this[] search(string search) {
}
How can I perform this ?
EDIT : I'm using generics, it's a generic class. Which means I don't have any clue on what the class which will extend mine will be. So no I can't just add the class name before the []...
EDIT 2: As it has been pointed out, returning an array of this doesn't make any sense (my mistake then). So what I want to do is return an array of the extending class type. For example :
public abstract class MappingObject {
public ExtendedClassType[] search (string search) {
}
}
Found the solution ._. I'm sorry it was quite simple...
public abstract class MappingObject<T> where T : new() {
public static List<T> search(string search) {
}
}
Upvotes: 4
Views: 136
Reputation: 64517
I'm not entirely sure what you are looking for, but based on a few clues in your question you might want to review something like the following (referred to as the Curiously Recurring Template Pattern):
public abstract class MyBaseClass<T> : where T : MyBaseClass<T>
{
public abstract T[] Search(string search);
}
public class DerivedClass : MyBaseClass<DerivedClass>
{
public override DerivedClass[] Search(string search)
{
return new DerivedClass[0];
}
}
This is possible, but I'm not sure if it is what you are looking for and I'd review to see if this was a good design choice or not, it feels a little leaky.
This particular idea is used in frameworks like CSLA.NET in order to expose to derived class strong references to themselves when inheriting from certain base classes. This is usually a "syntax sugar" thing, and avoids having to cast up a lot just to use things on your own type when retrieving them from base classes. The base class itself still should not understand what types are deriving from it.
Eric Lippert talks about this pattern on his old MS blog. It has its pitfalls and he exposes a manner in which it can be abused. I personally stand by the approach that being aware of these pitfalls and possibilities for abuse is good enough, so long as things are tested I'm happy to use something that might go against guidelines or principles if the case is clear (there isn't enough additional information to understand if it is clear in this particular case). Eric's post ends:
All that said, in practice there are times when using this pattern really does pragmatically solve problems in ways that are hard to model otherwise in C#; it allows you to do a bit of an end-run around the fact that we don't have covariant return types on virtual methods, and other shortcomings of the type system. That it does so in a manner that does not, strictly speaking, enforce every constraint you might like is unfortunate, but in realistic code, usually not a problem that prevents shipping the product.
My advice is to think very hard before you implement this sort of curious pattern in C#; do the benefits to the customer really outweigh the costs associated with the mental burden you're placing on the code maintainers?
The best use of this pattern I have seen left all the recurring parts internal or protected and the public API was left alone.
Upvotes: 4
Reputation: 35726
Do you mean,
public class YourClass
{
public T[] Search<T>(string search, Convertor<SearchResult, T> convertor)
{
...
List<SearchResult> results = ...
return results.ConvertAll(convertor).ToArray();
}
}
This way, you delegate the conversion to the caller who will know what type is passed as the generic type parameter.
Upvotes: 0
Reputation: 6502
'this' means this instance of a class, so your code at the minute basically says 'I want to return an array of this instance of MyClass' which doesn't really make sense.
I think you want to say 'I want to return an array of this type of class object'
So you specify the return type of the method as the class name.
public YourClassName[] Search(string search)
{
}
Upvotes: 0