在方法的参数和返回类型上使用不同的泛型类型

时间:2011-06-07 16:34:22

标签: c# generics

我正在研究一个泛型实用程序方法,该方法接受泛型参数并返回泛型类型 - 我希望这有意义! - 但我希望返回类型与参数的类型不同。

如果我用伪代码模拟它,我认为这应该是这样的:

public static IEnumerable<R> DoSomethingAwesome<T>(T thing) 
{
    var results = new List<R>();

    for (int xx = 0; xx < 5; xx++)
    {
        results.Add(thing.ToRType(xx));
    }

    return results;
}

由于泛型无法推断返回类型,我将如何做这样的事情?到目前为止,我的谷歌已经让我失望了。

5 个答案:

答案 0 :(得分:8)

// You need this to constrain T in your method and call ToRType()
public interface IConvertableToTReturn
{
    object ToRType(int someInt);
}

public static IEnumerable<TReturn> DoSomethingAwesome<T, TReturn>(T thing)
    where T : IConvertableToTReturn
{
    Enumerable.Range(0, 5).Select(xx => thing.ToRType(xx));
}

答案 1 :(得分:1)

您可以将返回类作为输出参数传递:

public static void DoSomethingAwesome<T,R>(T thing, out IEnumerable<R> output) 

然后可以推断出这一点。

答案 2 :(得分:1)

static IEnumerable<R> Function<T,R> (T h)
{
    for (int xx = 0; xx < 5; xx++)
    {
        yield return h.ToRType(xx);
    }
    yield return break;
}

IEnumerable<class2> res =  Function<class1, class2>(class1Object);

答案 3 :(得分:0)

您需要显式指定返回泛型类型作为方法的类型参数。

类似的东西:

public static IEnumerable<R> DoSomething<T,R>(IEnumerable<T> things, Func<T,R> map) 
{
    foreach (var t in things) { yield return map(t); }
}

这基本上是Linq IEnumerable扩展方法“Select”所做的..

答案 4 :(得分:-1)

泛型可以是令人敬畏的,非常令人敬畏的痛苦。正如其他人所说,你可以使用多种方式来获得多个输入参数,真正的诀窍在于使用传入的类型做一些有用的事情。

在你的例子中

public static IEnumerable<Ret> Fn<Ret,Parm>(IList<Parm> P)  
        {
            var Results = new List<Ret>();
            foreach(Parm p in P)
            {
                Results.Add(p.ToType());
            }
            return Results;
        }

由于编译器不知道如何处理P.ToType()

,因此无法编译

所以你说得好我可以添加我的param类型所需的功能但是这不起作用,因为编译器再次不知道具体版本或Ret将是什么,你的返回列表是Ret类型类型为returnType

public class RetunType
        {
            public int a;
        }

        public class Input
        {
            public int x;
            public RetunType TotoAReturnType()
            {
                return new RetunType() { a = this.x };
            }
        }

        public static IEnumerable<Ret> Fn<Ret, Parm>(IList<Parm> P) where Parm : Input  where Ret:RetunType
        {
            var Results = new List<Ret>();
            foreach (Parm p in P)
            {
                Results.Add(p.TotoAReturnType());
            }
            return Results;
        }

要解决此问题,您可以添加通用接口,以便在任何类型支持通用接口时您的功能可以正常工作

喜欢这个

public interface ToType<R>
{
    R ToType();
}
public class B
{
    public int x; 
}

public class A : ToType<B>
{
    string x = "5";
    public B ToType()
    {
        B aB = new B();
        aB.x = int.Parse(x);
        return aB;
    }
}
public static IEnumerable<Ret> Fn<Ret,Parm>(IList<Parm> P)  where Parm : ToType<Ret>
{
    var Results = new List<Ret>();
    foreach(Parm p in P)
    {
        Results.Add(p.ToType());
    }
    return Results;
}
static void Main(string[] args)
{
    List<A> inLst = new List<A>() { new A()};
    var lst = Fn<B, A>(inLst);
}

泛型很棒但是我强烈建议使用接口来支持你在这些函数中的操作。