A few days ago I learned something new.
For certain unfortunate reasons sometimes one is forced to downcast an object before sending it to a method which takes a generic parameter. Again, this isn't an ideal case as it seems less generic, but just in case someone else has found themselves in such a pickle because of other constraints, I hope you find this solution as helpful as I have. In C# 4.0 the dynamic was introduced.
Given a couple of tools that inherit from a tool object:
And a method that takes the generic:
public class ToolHandler {
public virtual void Tighten<T>(T tool) {
}
}
How does one downcast the object from a list before calling the method without checking each type in a list?
public List<Tool> Tools { get; set; }
var _toolHandler = new ToolHandler();
List<Tool> tools = new List<Tool>{new Wrench(), new ScrewDriver()};
*************Former sloppy way******************
foreach(var tool in tools){
if (tool is Wrench) {
_toolHandler.Tighten((Wrench) tool);
}
if (tool is ScrewDriver) {
_toolHandler.Tighten(( ScrewDriver)tool);
}
}
****************************************************
The answer- use a dynamic.
foreach(var tool in tools){
_toolHandler.Tighten((dynamic) tool);
}
*Special thanks to M.Babcock on stackoverflow for answering my co-worker's and my question. http://stackoverflow.com/ questions/9116034/downcast- instance-using-its-type
Feel free to paste this inside Rextester (http://rextester.com/runcode) or wherever you would like to run it for an example. Hopefully the link still works too http://rextester.com/live/IJWT40081.
For certain unfortunate reasons sometimes one is forced to downcast an object before sending it to a method which takes a generic parameter. Again, this isn't an ideal case as it seems less generic, but just in case someone else has found themselves in such a pickle because of other constraints, I hope you find this solution as helpful as I have. In C# 4.0 the dynamic was introduced.
Given a couple of tools that inherit from a tool object:
public abstract class Tool {
}
public class Wrench : Tool {
}
public class ScrewDriver : Tool {
}
And a method that takes the generic:
public class ToolHandler {
public virtual void Tighten<T>(T tool) {
}
}
How does one downcast the object from a list before calling the method without checking each type in a list?
public List<Tool> Tools { get; set; }
var _toolHandler = new ToolHandler();
List<Tool> tools = new List<Tool>{new Wrench(), new ScrewDriver()};
*************Former sloppy way******************
foreach(var tool in tools){
if (tool is Wrench) {
_toolHandler.Tighten((Wrench)
}
if (tool is ScrewDriver) {
_toolHandler.Tighten((
}
}
****************************************************
The answer- use a dynamic.
foreach(var tool in tools){
_toolHandler.Tighten((dynamic)
}
*Special thanks to M.Babcock on stackoverflow for answering my co-worker's and my question. http://stackoverflow.com/
Feel free to paste this inside Rextester (http://rextester.com/runcode) or wherever you would like to run it for an example. Hopefully the link still works too http://rextester.com/live/IJWT40081.
using System;
using System.Collections.Generic;
namespace Rextester
{
public class Program
{
public abstract class Tool {
}
public class Wrench : Tool {
}
public class ScrewDriver : Tool {
}
public class ToolHandler {
public virtual void Tighten<T>(T tool) {
Console.WriteLine(typeof(T));
}
}
public static void Main(string[] args)
{
List<Tool> tools = new List<Tool>{new Wrench(), new ScrewDriver()};
var handler = new ToolHandler();
foreach(var tool in tools){
handler.Tighten((dynamic)tool);
}
}
}
}
using System.Collections.Generic;
namespace Rextester
{
public class Program
{
public abstract class Tool {
}
public class Wrench : Tool {
}
public class ScrewDriver : Tool {
}
public class ToolHandler {
public virtual void Tighten<T>(T tool) {
Console.WriteLine(typeof(T));
}
}
public static void Main(string[] args)
{
List<Tool> tools = new List<Tool>{new Wrench(), new ScrewDriver()};
var handler = new ToolHandler();
foreach(var tool in tools){
handler.Tighten((dynamic)tool);
}
}
}
}