In C#, is there a way to create a method which could return either a class or another class?
Short answer to the title of the question: no, but....
A method cannot return a unique type or else another type, which have nothing in common, which are completely distinct.
We can return only one integral numeric value like an int, or one value type instance like a struct, or one reference value like a class, or so a tuple, and also an interface.
Why methods return just one kind of parameter in normal conditions?
Unless we have a base class or an interface common to these types.
For example if Predicate<>
or FilterDefinition<>
implements IMyInterface
, we can return one or the other object as this interface:
IMyInterface MyMethod()
{
if ( ... )
return (IMyInterface)new Predicate<BsonDocument>();
else
return (IMyInterface)new FilterDefinition<BsonDocument>();
}
So if Predicate<>
or FilterDefinition<>
have a non-generic ancestor to upcast the object to return, or implements a non-generic interface to return it, it will work.
Non-generic because we don't have true generic polumorphism via the diamond operator available in C# yet.
I just see that these generic types seems to come from MongoDB, and if it is the case, they do not have something in common according to this documentation.
Here is a quick idea, a hack, perhaps not very clean, or not: return a tuple (or a struct or a class) having first item of type A and second item of type B.
One is null and the other not null.
So the caller can check that and use what is provided.
For example:
(Predicate<BsonDocument> predicate, FilterDefinition<BsonDocument> filterdefinition) MyMethod()
{
if ( ... )
return (new Predicate<BsonDocument>(), null);
else
return (null, FilterDefinition<BsonDocument>());
}
Used like that:
var result = MyMethod();
if ( result.predicate != null && result.filterdefinition != null )
throw new SystemException("Two instances provided: only one is expected.");
else
if (result.predicate != null)
{
...
}
else
if (result.filterdefinition != null)
{
...
}
else
throw new SystemException("No instance provided: one is expected.");
Throwing exceptions here is only very scrupulous and may be omitted, or not...