关于泛型,继承和链接的棘手问题

时间:2009-10-22 00:23:07

标签: c# generics inheritance lambda

上下文 - read this

问题:

 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;
        }
    }

解决方案:

 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;
        }
    }

这是一种如何'模仿'能够返回派生类型的基类方法的技术(否则我的b不能再次调用buzz())。

进一步使foo / bar通用(这仍然可以正常工作):

  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;
        }
    }

问题是 -
如何将lambda传递给知道fizz的{​​{1}}方法及其属性,而不显式传递类型参数

可能反映我正在寻找的代码的破碎代码:

tbuzz

想知道这是否可行。如果没有 - 为什么?

理论上 - 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; } } 知道底下有一个foo<T>

有没有其他方法可以创建基本方法或模仿它支持链接这样的类?

3 个答案:

答案 0 :(得分:1)

我不认为你想要完成的是可能的。从理论上讲,你需要的是某种约束,如:

where TBuzz : T<inner> 

意味着TBuzz需要是T的内部泛型类型。据我所知,这是不可能的。

答案 1 :(得分:0)

此?

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;
    }
}

答案 2 :(得分:0)

起初我以为我用Thrush combinator

取得了进展
public static T fizz<T>(this T t, Func<T, T> f)
{ return f(t); }

但这似乎是一个死胡同。无论如何都要发布它,以防你可以改进它。