簡體   English   中英

在方法的參數和返回類型上使用不同的泛型類型

[英]Using different generic types on a method's argument and return type

我正在研究一個通用實用程序方法,它接受一個通用參數並返回一個通用類型——我希望這是有道理的。——但我希望返回類型與參數不同。

如果我用偽代碼模擬它,我認為這應該是這樣的:

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

由於 generics 無法推斷返回類型,我將如何 go 做這樣的事情? 到目前為止,我的 Google-Fu 讓我失望了。

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

您可以將返回的 class 作為 output 參數傳遞:

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

這可以推斷出來。

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

您需要將返回的泛型類型顯式指定為方法的類型參數。

就像是:

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”所做的。

Generics 可能很棒,也很痛苦。 正如其他人所說,您可以使用多種方法來擁有多個輸入參數,真正的技巧是對傳入的類型進行有用的操作。

在你的例子中

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()

所以你說得好,我可以將所需的 function 添加到我的參數類型中但這也不起作用,因為編譯器再次不知道具體版本或 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;
        }

要解決此問題,您可以添加一個通用接口,以便您的 function 可以在任何類型支持通用接口的情況下工作

像這樣

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

Generics 很棒,但我強烈建議您使用接口來支持您在這些功能中的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM