Using a Func<> over an interface?

Cyril Gandon picture Cyril Gandon · Jul 30, 2012 · Viewed 8k times · Source

I have an already existing generic class

public class Foo<T>
{
    private T _item;
    public Foo(T item){ _item = item;}
}

I have to create a method which will return a certain property of T.
I see two solutions here.

  1. Creating an interface :

    public const string TestVar = "bar";
    public interface INamable { string Name { get; } }
    public class Bar : INamable
    {
        public string Name { get { return TestVar; } }
    }
    
    public class Foo<T> where T : INamable
    {
        private T _item;
        public Foo(T item) { _item = item; }
        public string GetName() { return this._item.Name; }
    }
    
    [TestMethod()]
    public void TestInterface()
    {
        var bar = new Bar();
        var foo = new Foo<Bar>(bar);
        Assert.AreEqual(TestVar, foo.GetName());
    }
    
  2. Passing a Func :

    public const string TestVar = "bar";
    public class Bar
    {
        public string Name { get { return TestVar; } }
    }
    
    public class Foo<T>
    {
        private T _item;
        private Func<T, string> _funcName;
        public Foo(T item, Func<T, string> funcName) { _item = item; _funcName = funcName; }
        public string GetName() { return _funcName.Invoke(_item); }
    }
    
    [TestMethod()]
    public void TestFunc()
    {
        var bar = new Bar();
        var foo = new Foo<Bar>(bar, b => b.Name);
        Assert.AreEqual(TestVar, foo.GetName());
    }
    

I go with the second solution, since I don't have to create an interface, and I'm lazy. Just have to add one parameter to the already call of the foo constructor.

Moreover, the Foo class can still be used with all sort of class, and I prefer it this way.

BUT, I'm not sure if it is the good way to use a Func? Is it still nice and SOLID? This is my first try to use a Func, that's why I'm asking myself!

A couple of months ago I used the first solution, with classic interface...

Answer

Thom Smith picture Thom Smith · Jul 30, 2012

The first solution (i.e. no Func) is far simpler. There is absolutely no need to invoke Func objects to implement a garden-variety property accessor.