Anonymous interface implementation

前端 未结 2 420
一个人的身影
一个人的身影 2020-12-12 06:13

I´ve read \'C# anonymously implement interface (or abstract class)\' thread for implementing an interface anonymously. But I wondered if this is also possible using .NET 2.0

相关标签:
2条回答
  • 2020-12-12 06:24

    .NET 2.0 also supported anonymous delegates, it's just that the syntax was a bit more verbose compared to lambdas, and type inference didn't work. And there were no extension methods in C# 2.0 (although you were able to use C# 3.0 and compile against .NET 2.0), which are the basis of LINQ and being able to operate on interfaces.

    Compare:

    • .NET 2.0: delegate(int i) { return (i < 5); }
    • .NET 3.5: i => i < 5

    .NET 2.0 also lacks common generic delegate signatures (Func and Action), but you can also easily define them yourself (for all combinations of parameters you like):

    public delegate void Action<T>(T item);
    public delegate Tresult Func<T, Tresult>(T item);
    

    So, whatever approach your linked answer used to mimic anonymous interfaces can be represented using .NET 2.0 delegates, at the expense of added verbosity. Making you ask yourself: "is this really that shorter to write?"

    [Update]

    If your interface is a single method interface, like:

    interface IFoo
    {
        string Bar(int value);
    }
    
    class SomeOtherClass
    {
        void DoSomething(IFoo foo);
    }
    

    then you might get rid of it entirely and simply use a delegate instead:

    class SomeOtherClass
    {
        void DoSomething(Func<int, string> bar);
    }
    
    new SomeOtherClass().DoSomething(delegate(int i) { return i.ToString(); });
    

    If you have an interface with many methods that you want to be able to implement inline in many different places, you can use something like this:

    interface IFoo
    {
        string GetSomething();
        void DoSomething(int value);
    }
    
    // conditional compile, only if .NET 2.0
    #if NET_2_0
    public delegate void Action<T>(T item);
    public delegate Tresult Func<Tresult>();
    #endif
    
    class DelegatedFoo : IFoo
    {
        private readonly Func<string> _get;
        private readonly Action<int> _do;
    
        public DelegatedFoo(Func<string> getStuff, Action<int> doStuff)
        {
            _get = getStuff;
            _do = doStuff;
        }
    
        #region IFoo members simply invoke private delegates
    
        public string GetSomething()
        { return _get(); }
    
        public void DoSomething(int value)
        { _do(value); }
    
        #endregion
    }
    

    Which would allow you to pass delegates to the DelegatedFoo class inline:

    var delegated = new DelegatedFoo(
        delegate() { return ""; }, // string GetSomething()
        delegate(int i) { }        // void DoSomething(int)
    );
    

    Using .NET 4 the C# 4.0 syntax it would look a bit cleaner due to syntactic sweetness of lambdas and named parameters:

    var delegated = new DelegatedFoo(
        getStuff: () => "",
        doStuff:  i => { }
    );
    
    0 讨论(0)
  • 2020-12-12 06:33

    I know that this may not be exactly what you are hoping for, but if you absolutely have to do it, you can use any of the mocking frameworks available to request an object which implements the interface and then add implementations for the methods. This is a standard practice in TDD.

    Also, you can simply use anonymous delegates to achieve most of your needs as per John Skeet's advice in the question your mention.

    0 讨论(0)
提交回复
热议问题