[英]Co/contravariance with Func<in T1, out TResult> as parameter
假設我有一個界面,如
public interface IInterface<in TIn, out TOut> {
IInterface<TIn, TOut> DoSomething(TIn input);
}
TIn
是禁忌 -variant,並TOut
為Co -variant。
現在,我希望調用者能夠指定一些要在輸入值上執行的函數,所以天真地我會在接口中添加以下方法:
IInterface<TIn, TOut> DoSomethingWithFunc(Func<TIn, TOut> func);
哪......不起作用。 TIn
現在需要協變,並且TOut
逆變。
我理解,我不能使用協變泛型類型作為方法的輸入,但我想我可以在嵌套泛型類型中使用它們,它本身指定方差( Func<in T1, out TResult>
)。
我嘗試使用co / contravariant類型創建一個新的委托類型,並更改接口以接受此類型的參數,但無效(相同的錯誤)。
public delegate TOut F<in TDlgIn, out TDlgOut>(TDlgIn input);
public interface IInterface<in TIn, out TOut> {
IInterface<TIn, TOut> DoSomethingWithFunc(F<TIn, TOut> func);
}
我有辦法讓編譯器開心嗎? 這是否可能(例如使用其他嵌套類型或其他通用參數)? 如果沒有,為什么不呢?
這可能不安全,因為您可以使用它來執行:
public class Id<I, O> : IInterface<I, O>
{
private Func<I, O> f;
public Id(Func<I, O> f) { this.f = f; }
public IInterface<I, O> DoSomething(I i) { this.f(i); return this; }
public IInterface<I, O> DoSomethingWithFunc(Func<I, O> newF) {
this.f = newF;
return this;
}
}
然后
Func<Animal, string> fa;
IInterface<object, string> oi = new Id<object, string>(_ => "");
Interface<Monkey, string> mi = oi; //safe
IInterface<Monkey, string> mi2 = mi.DoSomethingWithFunc(fa);
oi.DoSomething("not an animal!");
此時,您將把一個string
傳遞給Func<Animal, string>
。
你試過這個嗎?
delegate TOut F<out TDlgIn, in TDlgOut>(TDlgIn input)
在傳遞代表時,共同/反向差異需要相反。 我不知道它是否有幫助。 不知道你可能想在這個方法中做些什么。
Error CS1961 Invalid variance: The type parameter 'TIn' must be covariantly valid on 'IInterface<TIn, TOut>.DoSomethingWithFunc(Func<TIn, TOut>)'. 'TIn' is contravariant.
你實際上要做的是,你是將共變量TOut類型作為'DoSomethingWithFunc'方法的參數傳遞。 這是不可能的,只有In類型只能作為參數傳遞,Out僅作為結果傳遞。 在您的示例中,您將TOut作為參數(它將傳遞給'DoSomethingWithFunc',因為TOut是您的Func的結果)。
網上有很多關於它的文章('covariantly valid'是什么意思,但我認為最好的解釋是: https : //blogs.msdn.microsoft.com/ericlippert/2009/12 / 03 /確切的規則換方差的有效性/
這意味着你可以將你的Func作為你的界面中的方法的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.