Tricky question about generics, inheritance and chaining

戏子无情 提交于 2020-01-14 10:25:11

问题


For context - read this.

Problem:

 class Program
    {
        static void Main()
        {
            var b = new bar();

            b.buzz().fizz().buzz().fizz(); //cool
            //              ^FAIL!!!...<------------------------------------
            Console.ReadLine();
        }
    }

    public class foo
    {
        public foo fizz() { return this; }
    }

    public class bar : foo
    {
        public bar buzz()
        {
            return this;
        }
    }

Solution:

 class Program
    {
        static void Main()
        {
            var b = new bar();

            b.buzz().fizz().buzz().fizz(); //cool stuff
            Console.ReadKey();
        }
    }

    public static class fooExtensions
    {
        public static T fizz<T>(this T t) where T : foo
        { return t; } 
    }

    public class foo{}

    public class bar : foo
    {
        public bar buzz()
        {
            return this;
        }
    }

This is a technique how to 'mimic' method of base class which is able to return back derived type (otherwise my b couldn't call buzz() again).

Going further and making foo/bar generic (this will still work fine):

  class Program
    {
        static void Main()
        {
            var b = new bar<buzz>();

            b.buzz().fizz().buzz().fizz(); //cool
            Console.ReadLine();
        }
    }

    public static class fooExtensions
    {
        public static T fizz<T>(this T t) where T : foo<buzz>
        { return t; }
    }

    public class buzz { public string name { get; set;} }

    public class foo<T> where T : buzz
    {}

    public class bar<T> : foo<T> where T : buzz
    {
        public bar<T> buzz()
        {
            return this;
        }
    }

And the question is -
how to pass lambda to fizz method that knows about tbuzz and it's properties without passing type parameter/s explicitly.

Broken code that might reflect what i'm looking for:

class Program
    {
        static void Main()
        {
            var b = new bar<buzz>();

            b.buzz().fizz(x=>x.name).buzz().fizz(); //not cool anymore
            //               ^FAIL!!!<---------------------------------
            Console.ReadLine();
        }
    }

    public static class fooExtensions
    {
        //NO IDEAS WHAT TO WRITE BELOW!!!
        public static T fizz<T, Tbuzz>(this T t, 
            Func<Tbuzz, object> superlambda)
            where T : foo<buzz>
            where Tbuzz : buzz 
        {
            return t;
        }
    }

    public class buzz { public string name { get; set;} }

    public class foo<T> where T : buzz
    {}

    public class bar<T> : foo<T> where T : buzz
    {
        public bar<T> buzz()
        {
            return this;
        }
    }

Wondering if that's possible. And if not - why?

Theoretically - foo<T> knows that there's a buzz underneath.

Are there any other approach how to create base method or mimic it that supports chaining for such a classes?


回答1:


I don't think what you're trying to accomplish is possible. Theoretically what you would need is some kind of constraint like:

where TBuzz : T<inner> 

meaning TBuzz needs to be the type that's the inner generic type of T. This isn't possible as far as I know.




回答2:


this?

class Program
{
    static void Main(string[] args)
    {
        var b = new bar();
        var a = b.buzz().fizz(x => x.name).buzz().fizz();
        Console.ReadLine();
    }
}

public static class fooExtensions
{
    public static T fizz<T>(this T t) where T : foo
    { return t; }

    public static T fizz<T>(this T t,
        Func<T, object> superlambda)
        where T : foo
    {
        return t;
    }
}

public class foo { public string name { get; set; } }

public class bar : foo
{
    public bar buzz()
    {
        return this;
    }
}



回答3:


At first I thought I made progress with a kind of Thrush combinator

public static T fizz<T>(this T t, Func<T, T> f)
{ return f(t); }

but that seems to be a dead end. Posting it anyway in case you can improve it.



来源:https://stackoverflow.com/questions/1604382/tricky-question-about-generics-inheritance-and-chaining

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!