Refactoring to avoid the use of dynamic Based on the answer to my question on StackOverflow, I have ended up with the following code:

public class ColumnDataBuilder&lt;T&gt;
{
    public abstract class MyListViewColumnData
    {
        public string Name { get; protected set; }
        public int Width { get; protected set; }
        public ColumnType Type { get; protected set; }
        public delegate TOUT FormatData&lt;out TOUT&gt;(T dataIn);

        protected abstract dynamic GetData(T dataRow);

        public string GetDataString(T dataRow)
        {
            dynamic data = GetData(dataRow);
            switch (Type)
            {
                case ColumnType.String:
                case ColumnType.Integer:
                case ColumnType.Decimal:
                    return data.ToString();
                case ColumnType.Date:
                    return data.ToShortDateString();
                case ColumnType.Currency:
                    return data.ToString("c");
                    break;
                case ColumnType.Boolean:
                    var b = (bool)data;
                    if (b) return "Y";
                    else return "N";
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

    }

    public class MyListViewColumnData&lt;TOUT&gt; : MyListViewColumnData
    {

        public MyListViewColumnData(string name, int width, ColumnType type, FormatData&lt;TOUT&gt; dataFormater)
        {
            DataFormatter = x =&gt; dataFormater(x); // Per https://stackoverflow.com/a/1906850/298754
            Type = type;
            Width = width;
            Name = name;
        }
        public Func&lt;T, TOUT&gt; DataFormatter { get; protected set; }
        protected override dynamic GetData(T dataRow)
        {
            return DataFormatter(dataRow);
        }
    }
 }


This is called from a factory method (in ColumnDataBuilder) as 

public MyListViewColumnData Create&lt;TOUT&gt;(string name, int width, ColumnType type, MyListViewColumnData.FormatData&lt;TOUT&gt; dataFormater)
{
    return new MyListViewColumnData&lt;TOUT&gt;(name, width, type, dataFormater);
}
public MyListViewColumnData Create(string name, int width, MyListViewColumnData.FormatData&lt;DateTime&gt; dataFormater)
{
    return new MyListViewColumnData&lt;DateTime&gt;(name, width, ColumnType.Date, dataFormater);
}
...


That, in turn, is called from my code as:

builder.Create("Date", 40, x =&gt; x.createdDate);


and 

private ListViewItem CreateListViewItem&lt;TDATA&gt;(IEnumerable&lt;ColumnDataBuilder&lt;TDATA&gt;.MyListViewColumnData&gt; columns, TDATA rowData)
{
    var item = new ListViewItem();
    foreach (var col in columns)
    {
        item.SubItems.Add(col.GetDataString(rowData));
    }
    item.SubItems.RemoveAt(0); // We generate an extra SubItem for some reason.
    return item;
}


How can I refactor this so that I'm not using dynamic, but still preserve the syntax as it currently exists in the code?
I don't think you need MyListViewColumnData class there, I would replace it with interface and move the GetDataString implementation to MyListViewColumnData&lt;TOut&gt;. And you don't need dynamic here, just use object instead (yes, it will use boxing for most cases except strings, but it's more efficient than dynamics).

public class ColumnDataBuilder&lt;T&gt;
{
    public interface IMyListViewColumnData
    {
        string Name { get; }
        int Width { get; }
        ColumnType Type { get; }
        string GetDataString(T dataRow);
    }

    public delegate TOut FormatData&lt;out TOut&gt;(T dataIn);

    public class MyListViewColumnData&lt;TOut&gt; : IMyListViewColumnData
    {
        public string Name { get; private set; }
        public int Width { get; private set; }
        public ColumnType Type { get; private set; }
        private readonly FormatData&lt;TOut&gt; _dataFormatter;

        public MyListViewColumnData(string name, int width, ColumnType type, FormatData&lt;TOut&gt; dataFormater)
        {
            _dataFormatter = dataFormater;
            Type = type;
            Width = width;
            Name = name;
        }
        public string GetDataString(T dataRow)
        {
            object data = _dataFormatter(dataRow);

            switch (Type)
            {
                case ColumnType.String:
                case ColumnType.Integer:
                case ColumnType.Decimal:
                    return data.ToString();
                case ColumnType.Date:
                    return ((DateTime)data).ToShortDateString();
                case ColumnType.Currency:
                    return ((decimal)data).ToString("c");
                case ColumnType.Boolean:
                    return (bool)data ? "Y" : "N";
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }

    public IMyListViewColumnData Create&lt;TOut&gt;(string name, int width, ColumnType type, FormatData&lt;TOut&gt; dataFormater)
    {
        return new MyListViewColumnData&lt;TOut&gt;(name, width, type, dataFormater);
    }

    public IMyListViewColumnData Create(string name, int width, FormatData&lt;DateTime&gt; dataFormater)
    {
        return new MyListViewColumnData&lt;DateTime&gt;(name, width, ColumnType.Date, dataFormater);
    }
}

public enum ColumnType
{
    String,
    Integer,
    Decimal,
    Date,
    Currency,
    Boolean
}


Update
In comments it was asked if you can extract interface for ColumnDataBuilder. Of course you can :), and the easiest way would be to use "Extract interface" refactoring from ReSharper :). If you still don't use it you'll have to do that manually (move the IMyListViewColumnData and FormatData&lt;TOut&gt; declarations out of ColumnDataBuilder&lt;T&gt; first):

public interface IColumnDataBuilder&lt;Tin&gt;
{
    IMyListViewColumnData Create&lt;TOut&gt;(string name, int width, ColumnType type, FormatData&lt;TOut&gt; dataFormater);
    IMyListViewColumnData Create(string name, int width, FormatData&lt;DateTime&gt; dataFormater);
}