[英]C# detect nullable reference type from generic argument of method's return type using reflection
[英]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.