Would you consider changing the interface or using an adapter here? - c#

I have an interface that returns an Enumerable of a type.
public interface IMapper
{
IEnumerable<IContract> Get(params object[] objects);
}
That basically takes one or more parameters whose type is also unknown and returns an Enumerable of any type that implements IContract. Feel free to suggest an alternative for this.
Now this looks simple enough and works. However, here's a scenario where it always returns one object (of type IContract). I can't change the fact that it returns only one object.
var escalationMapper = _factory.GetEscalationMapper();
//we only get one object with a list of triggers but the interface returns a list. Change the interface?
var escalations = escalationMapper.Get(trackingGroupCode);
_factory.Release(escalationMapper);
var contracts = escalations as IList<IContract> ?? escalations.ToList();
response = Request.CreateResponse(!contracts.Any()
? HttpStatusCode.NotFound : HttpStatusCode.OK, contract);
The line of code we're interested is what follows the comment because I don't feel comfortable returning just one object and calling it a list. There are other usages of the Get() method that returns lists proper This just happened to return at most 1 object..
Is it reasonable to return a single object as a list, or is there a better way to implement this?

Like I said in the comments, there is nothing wrong design-wise with your code. Even if the particular place where you call Get is guaranteed to return at most a single item within the returned list, that doesn't mean it's going to be guaranteed everywhere else that calls IMapper.Get.
If you really want to simplify it so that it returns the single object instead of a one-length list, though, I wouldn't recommend changing the interface to have an additional method, either. This would break all classes that implement IMapper and force you to implement that new method, even in places where the new method wouldn't add anything useful. This would be an especially big problem if anyone else uses your code for their own purposes, as it would force them to perform the rewrite as well.
One thing you could do to get around that issue, however, is to instead declare the new method as an extension method:
public static class IMapperExtensions
{
public static IContract GetSingle(this IMapper mapper, params object[] objects)
{
return mapper.Get(objects).FirstOrDefault();
}
}
Then you can call it like so:
var escalation = escalationMapper.GetSingle(trackingGroupCode);
This will give you the functionality you need without breaking any existing implementations of your interface.

I agree with #Abion47 and #chrylis comments - 0 or 1 items is a perfectly valid case for an collection of items.
However - if you disagree and still want a way to convey a single element without IEnumerable semantics, you could overload Get with a method that takes a single object and returns a single IContract. This would take precedence over the params[] overload, since object would be a better match for a single input than params[] object.
This would look like:
public interface IMapper
{
IContract Get(object input);
IEnumerable<IContract> Get(params object[] input);
}
Assuming a null value means not found, your calling code would become:
var escalationMapper = _factory.GetEscalationMapper();
//we only get one object with a list of triggers but the interface returns a list. Change the interface?
var escalation = escalationMapper.Get(trackingGroupCode);
_factory.Release(escalationMapper);
response = Request.CreateResponse(contract == null ? HttpStatusCode.NotFound : HttpStatusCode.OK, contract);
I have to caution that it feels odd suggesting this, and I think it introduces dishonesty into the interface. I also think there is great potential to break any existing code that also calls the interface with a single input.
As for replacing object, you could always add some marker interface like IContractInput and pass that into Get instead of object:
public interface IContractInput { /* Intentionally empty */ }
And then, mark any input class with IContractInput:
public class SomeInput : IContractInput { /* implementation.. */ }
That way the methods could be strongly typed to take IContractInput instead of a generic object type.

It's a tradeoff. The goal is to fit the type expected by the client. The tradeoff is between 1) having an additional class and 2) forcing an existing type to change.
The pro of 1) is that an existing type remains intact (assuming it does presently make the most sense as the type it is, returning a single IContract); the con of 1) is that it requires more code and more dependencies.
The pro of 2) is that code size and number of dependencies remain lower; the con of 2) is that you subvert the project's types design by changing a type to return a list that will always contain a single element, purely for the sake of the client's expectations.
In strongly typed languages, the types system is intended to be there as an aid to the programmer. The greater verbosity buys the benefits of the type system, and subverting that system doesn't help very much with reducing the verbosity, yet loses the benefits of that type system. As such, I would resolve this in strongly-typed languages with an adapter, not by changing the interface.
In other words, resolve the situation with the principle of least surprise ( https://en.wikipedia.org/wiki/Principle_of_least_astonishment ). If another programmer on the project (or you, yourself, in some months' time) would ordinarily expect an instance of EscalationMapper to return a sole IContract, and so would be surprised to see it return an IEnumerable, then use an adapter ( https://en.wikipedia.org/wiki/Adapter_pattern ). If, conversely, they'd be surprised to see it return a single item, then change the interface.

Related

Set type dynamically for method call

I have a static function:
public static MyCollection<T> Parse<T>(string? json) where T : BaseClass
{
...
}
And it works fine. It makes decisions internally based on the type and produces the correct collection.
But, the collection I want is based on a file name coming in from another source and I was hoping to have one collection and dynamically set the type, as in:
Type t;
if (name == "Certain name") t = typeof(CertainChildClassOfBaseClass);
if (name == "Other name") t = typeof(OtherChildClassOfBaseClass);
var myCollection = ParsingService.Parse<t>(jsonString);
This obviously doesn't work, but is what I'm trying possible? I don't really want to write a bunch of if/else blocks with nearly identical content just so each one can have a different type (I already wrote those type-specific blocks inside the Parse function - doing the same branching twice seems like maybe I've made a more fundamental mistake). I am open to suggestions on how to do this the "right" way. Maybe I have to do this with reflection, which doesn't thrill me, but isn't the end of the world. One possible issue is the my parsing service is static.
Help is always appreciated.
Usually, I would recommend making Parse non generic, and then have a generic overload:
public static MyCollection<BaseClass> Parse(Type type, string? json)
{
...
}
public static MyCollection<T> Parse<T>(string? json) where T : BaseClass
{
return (MyCollection<T>)Parse(typeof(T), json);
}
But you can't make MyCollection contravariant because it's a concrete class, so that cast is illegal. And anyway, contravariant containers are dangerous to use (just look at arrays, for example).
The other method is to use reflection to get the version of the method you want (a process known as "closing" the generic type):
var genericMethod = typeof(/* class containing Parse */).GetMethod("Parse");
var method = genericMethod.MakeGenericMethod(type); // type will be substituted for your 'T', above
object collection = method.Invoke(json); // call the method
And here we hit another snag: collection's type will be object, and you need to cast it to something else. But you can't use MyCollection<T> because you don't know T, and you can't use MyCollection<BaseClass> because, well, no contravariance, again.
So really the main blocker is that MyCollection type. As long as it is that way, you have no easy way to go around it. You could instead return a non generic collection, like ICollection or IList, but then you lose type safety and you'll have to keep casting more later. It's up to you, really.

Can A subclass be downcast while sent as a parameter to an overloaded function

I have a superClass called Block and another 3 subclasses. the class I want to implement contains 3 overloaded functions each one takes an object of one of the subclasses as a parameter. When I use one of these function, I only have a Block object (An object from the superClass). My question is what is the cleanest way to choose which function to call.
What I did until now is if conditions on the object type then casting it. but it seems unclean.
Those are the overloaded functions.
public void WriteBlock(TableBlock block) { }
public void WriteBlock(TextBlock block) { }
public void WriteBlock(ListBlock block) { }
And This is The function I want to implement.
public void WriteBlocks(List<Block> blocks)
{
BlockWriter w = new BlockWriter();
foreach (var block in blocks)
{
w.WriteBlock(block);
}
}
Note that I have no access on the Blocks classes.
Yes, it is possible using the dynamic type which allows for this.
If you use:
foreach (var block in blocks)
{
w.WriteBlock(block as dynamic);
}
It should call the intended WriteBlock overload.
This is described in greater length in another question: https://stackoverflow.com/a/40618674/3195477
And also here: method overloading and dynamic keyword in C#.
Caveats:
I am not sure if there is any runtime penalty associated with this type of dynamic "cast".
Also whenever I see this pattern it makes me wonder if the class hierarchy could be improved. i.e., should whatever WriteBlock will do actually be moved inside the Block classes? That might be "more polymorphic". Also using dynamic could be a somewhat fragile approach, as you can add new Block derived types and forget to an an overloaded WriteBlock for them, which may cause an error. (This is more evidence that some of WriteBlock should be incorporated into the Block classes themselves).
For instance, add a virtual PrepareForWriting() to the base Block class, which returns a BlockWritable. Then you only need one WriteBlock(BlockWritable data) to do the writing work. BlockWritable could be a string, Json, XML, etc. This assumes you are able to modify the Block classes (which it seems you cannot).
No. Given this:
public void WriteBlocks(List<Block> blocks)
the only thing the compiler knows about each item in the list is that it is a Block. That's all it should know. That's what makes polymorphism possible. There can be any number of classes that inherit from Block, but within this context those distinctions don't matter.
But if all the compiler knows is that each item is a Block, it can't know whether any individual item might be a TableBlock, TextBlock, or some other inherited type. If, at compile time, it doesn't know what the runtime type will be, it can't know whether there even is an overload for that specific type.
Suppose what you're trying to do could compile, because you have an overload for every type that inherited from Block. What would or should happen if you added a new type - class PurpleBlock : Block - and there was no overload for it? Should this no longer compile just because you added a new type?
If the method that calls WriteBlocks knows what sort of Block is in the list, then it can supply that information:
public void WriteBlocks<TBlock>(List<TBlock> blocks) where TBlock : Block
Now you can call WriteBlock<TextBlock>(listOfTextBlocks) and the compiler will know that each item in the list is a TextBlock, not just a Block.
It follows, then, that BlockWriter would have to be generic also so that you could have different implementations for different types of Block. It might make more sense to inject it. Either way, you're likely to perceive that you've "moved" the problem. If the class that calls WriteBlocks "knows" the type of the Block, then it might make more sense for that method to determine the type of BlockWriter to use.
As mentioned in your comment, the list might include different types of Block, not just one. That requires either a method or a class that returns a specific BlockWriter depending on the type of Block. That means runtime type-checking, which isn't ideal, but it's not too bad if you keep it in one place.
Here's a simple example:
public class BlockWriterFactory
{
public BlockWriter GetBlockWriter(Block block)
{
if (block is TextBlock)
return new TextBlockWriter();
if (block is TableBlock)
return new TableBlockWriter();
if (block is ListBlock)
return new ListBlockWriter();
// this could be a "null" class or some fallback
// default implementation. You could also choose to
// throw an exception.
return new NullBlockWriter();
}
}
(A NullBlockWriter would just be a class that does nothing when you call its Write method.)
This sort of type-checking isn't ideal, but at least this keeps it isolated into one class. Now you can create (or inject) an instance of the factory, and call GetBlockWriter, and the rest of your code in that method still wouldn't "know" anything about the different types of Block or BlockWriter.
BlockWriter w = new BlockWriter();
would become
BlockWriter w = blockWriterFactory.GetBlockWriter(block);
...and then the rest would still be the same.
That's the simplest possible factory example. There are other approaches to creating such a factory. You could store all of your implementations in a Dictionary<Type, BlockWriter> and attempt to retrieve an instance using block.GetType().

Difference between returning reference vs not returning anything

Is there a difference between these two methods?
public class A
{
public int Count { get; set; }
}
public A Increment(A instance)
{
instance.Count++;
return instance;
}
public void Increment(A instance)
{
instance.Count++;
}
I mean, apart from one method returning the same reference and the other method not returning anything, both of them accomplish the same thing, to increment the Count property of the reference being passed as argument.
Is there an advantage of using one against the other? I generally tend to use the former because of method chaining, but is there a performance tradeoff?
One of the advantages of the latter method, for example, is that one cannot create a new reference:
public void Increment(A instance)
{
instance.Count++;
instance = new A(); //This new object has local scope, the original reference is not modified
}
This could be considered a defensive approach against new implementations of an interface.
I don't want this to be opinion based, so I am explicitly looking for concrete advantages (or disadvantages), taken out from the documentation or the language's specification.
One of the advantages of the latter method, for example, is that one cannot create a new reference.
You could consider that one of the disadvantages. Consider:
public A Increment(A instance)
{
return new A { Count = instance.Count +1 };
}
Or
public A Increment()
{
return new A { Count = this.Count +1 };
}
Apply this consistently, and you can have your A classes being immutable, with all the advantages that brings.
It also allows for different types that implement the same interface to be returned. This is how Linq works:
Enumerable.Range(0, 1) // RangeIterator
.Where(i => i % 2 == 0) // WhereEnumerableIterator<int>
.Select(i => i.ToString()) // WhereSelectEnumerableIterator<int, string>
.Where(i => i.Length != 1) // WhereEnumerableIterator<string>
.ToList(); // List<string>
While each operation acts on the type IEnumerable<int> each result is implemented by a different type.
Mutating fluent methods, like you suggest, are pretty rare in C#. They are more common in languages without the sort of properties C# supports, as it's then convenient to do:
someObject.setHeight(23).setWidth(143).setDepth(10);
But in C# such setXXX methods are rare, with property setters being more common, and they can't be fluent.
The main exception is StringBuilder because its very nature means that repeatedly calling Append() and/or Insert() on it with different values is very common, and the fluent style lends itself well to that.
Otherwise the fact that mutating fluent methods aren't common means that all you really get by supplying one is the minute extra cost of returning the field. It is minute, but it's not gaining anything when used with the more idiomatic C# style that is going to ignore it.
To have an external method that both mutated and also returned the mutated object would be unusual, and that could lead someone to assume that you didn't mutate the object, since you were returning the result.
E.g upon seeing:
public static IList<T> SortedList(IList<T> list);
Someone using the code might assume that after the call list was left alone, rather than sorted in place, and also that the two would be different and could be mutated separately.
For that reason alone it would be a good idea to either return a new object, or to return void to make the mutating nature more obvious.
We could though have short-cuts when returning a new object:
public static T[] SortedArray<T>(T[] array)
{
if (array.Length == 0) return array;
T[] newArray = new T[array.Length];
Array.Copy(array, newArray, array.Length);
Array.Sort(newArray);
return newArray;
}
Here we take advantage of the fact that since empty arrays are essentially immutable (they have no elements to mutate, and they can't be added to) for most uses returning the same array is the same as returning a new array. (Compare with how string implements ICloneable.Clone() by returning this). As well as reducing the amount of work done, we reduce the number of allocations, and hence the amount of GC pressure. Even here though we need to be careful (someone keying a collection on object identity will be stymied by this), but it can be useful in many cases.
Short answer - it depends.
Long answer - I would consider returning the instance of the object if you are using a builder pattern or where you need chaining of methods.
Most of other cases do look like a code smell: if you are in control of the API and you find a lot of places where your returned object is not used, so why bother with extra effort? possibly you'll create subtle bugs.

Dynamically create or set the return type of a function in the function

I am attempting to create a function where the return type is determined at run-time. I know I could just return an object or dynamic, however my aim is to have the typed object returned, and be recognized by the compiler and InteliSense.
I know I could cast my object after it has been returned and that would be the easiest thing to do to implement this, but that is just not the programming spirit.
Here is an example of what I'm trying to create
Note: I do not actually want Buttons and Grids... that is just for this example.
Type T;
public T Question(bool aBool)
{
if (aBool)
{
T = typeof(Button);
return new Button();
}
else
{
T = typeof(Grid);
return new Grid();
}
}
Now, this obviously doesn't work and I understand why. But I want to know if anyone has a way that does work, or if this is not possible with the current state of C#.
Edit: A response to comments... I understand this would seem like "magic", and I do understand that the compiler will have to figure out what my result is for this to work. The compiler/Intellisense/Visual Studio already does this for many other things. While these things are can simple like detecting unreachable code, or drawing visual previews. I am curious if this is an implemented feature.
The only possible way for the consumer of such a method to actually rely on the fact that the return type is dynamic is if, at least for that one method call, the return type is statically known at compile time.
There is a specific feature for a method that has some type unknown at the time the method is written, but fixed when a particular call to that method is make. That feature is called "generics".
public T Foo<T>()
where T : new()
{
return new T();
}
That's really the only available option for a truly dynamic return type that has much potential for really being useful.
If that's not what you want, or that is not a workable option for you, then odds are pretty high your method shouldn't have a dynamically changing return type. Instead it should have a fixed return type of some more generalized type that can have multiple implementations. Generally this would mean an interface, to which you can return one of any number of possible implementations. This should be done if the caller doesn't need to really know or care what the implementation is, but rather all they need to know is that they are given some implementation of an interface that exposes all of what they need. In your case, perhaps something like Control would be workable, if the caller only need to know that they are given some type of control, and to which the API of Control provides everything that they need to do with it.
You can use Dynamic keyword in this case
eg:
public dynamic CreatObj(string caller)
{
if (caller.equals("x"))
return x;
else
return y;
}
You can use a type if it has a parameterless constructor and you mark your generic with the new constraint. If you want to do more than that it get more difficult you need to use refection or activator.

Is there a benefit to using the c# out/ref keyword to "return" > 1 item in a method, instead of an object

Returning multiple things from a method, involves either:
returning an object with properties OR
using the out keyword to simply modify incoming parameters
Is there a benefit to using one system or the other? I have been using objects, but just discovered the out keyword, so wondering if I should bother refactoring.
You shouldn't bother refactoring just to utilize out parameters. Returning a class or struct would be preferred as long as structure is reusable.
A common use for out parameters which I would suggest using is to return a status for a call with that is possible to fail. An example being int.TryParse.
It has the possibility of failing, so returning a bool makes it easy to determing whether or not you should use the out parameter.
Another possible solution to returning multiple values from a method would be to use a Tuple. They can return n number of results. E.g.
public Tuple<bool, bool, string> MyMethod()
{
return new Tuple<bool, bool, string>(false, true, "yep");
}
In general, if the object that you are returning is not used anywhere else outside of the return value of your method or a group of similar methods, it is a good indication that you should refactor. When you need to create a special class simply to be used as a return value of a method, it means that you are working around C#'s inability to return multiple values from a method, so the out keyword may be a very good option for you.
On the other hand, if you use the multi-part return value in other places, such as storing them in collections or passing as arguments to other methods, there's probably no need to refactor, because the return object is meaningful.
Compare these two methods:
interface DictionaryReturn<T> {
T Value {get;}
bool Success {get;}
}
...
class Dictionary<K,V> {
...
public DictionaryReturn<V> TryGetValue(K key) {
...
}
}
or
class Dictionary<K,V> {
...
public bool TryGetValue(K key, out V res) {
...
}
}
The first case introduces a special DictionaryReturn<T> class that provides the value and an indicator that the value was found in the dictionary. There is rarely, if ever, a reason to store or use DictionaryReturn<T> objects outside the call to TryGetValue, so the second option is better. Not surprisingly, it is the second option that the designers of the .NET collections library have implemented.
I prefer to use Object with properties. If you use out keyword, you need to define it in other line. It is not as clear as return Object;
The reason to use out keyword is to ensure that code inside the method always sets a value to the out parameter. It's a compile time check that what you intended to do in the function, you did do.

Categories