generic-variance

How does contravariance work with Func delegate in .net core

心已入冬 提交于 2021-02-05 07:00:52
问题 I have the following piece of code where I am trying to write a generic validation rule for my domain objects. while doing so I have an issue to deal Func delegate supporting variance public class Person { } public class Employee : Person { } internal interface IValidation<T> where T: Person { void AddValidationRule(Func<T,bool> predicateFunction); } internal class BaseValidation : IValidation<Person> { void IValidation<Person>.RegisterValidationRules(Person person) { } } internal class

Implicit resolution fails for a contravariant type with a type bound

核能气质少年 提交于 2020-06-26 14:59:27
问题 The following code compiles: class X[U, T <: U] object X { implicit def genericX[U, T <: U]: X[U, T] = new X[U, T] } implicitly[X[String, String]] // compiles When we make T covariant ( class X[U, +T <: U] ) it compile as well: class X[U, +T <: U] object X { implicit def genericX[U, T <: U]: X[U, T] = new X[U, T] } implicitly[X[String, String]] // compiles When we make T contravariant ( class X[U, -T <: U] ), compiler fails to materilize implicitly[X[String, String]] . Strangely enough, it is

How can I implement a method that accepts a Consumer<Optional<T>> that is contravariant in T?

元气小坏坏 提交于 2020-01-06 17:59:52
问题 In the following sample, I can pass a Consumer<Optional<Integer> to foo , but not a Consumer<Optional<Number>> . On the other hand, I can pass either type to foo2 , but then I can't call the accept method of the consumer from the method body. Is there a way to change the foo method so that this works? My initial intuition was to try void foo(Consumer<Result<? super T>> c) but that apparently doesn't mean what I would assume. import java.util.Optional; import java.util.function.Consumer;

How can I implement a method that accepts a Consumer<Optional<T>> that is contravariant in T?

北战南征 提交于 2020-01-06 17:59:15
问题 In the following sample, I can pass a Consumer<Optional<Integer> to foo , but not a Consumer<Optional<Number>> . On the other hand, I can pass either type to foo2 , but then I can't call the accept method of the consumer from the method body. Is there a way to change the foo method so that this works? My initial intuition was to try void foo(Consumer<Result<? super T>> c) but that apparently doesn't mean what I would assume. import java.util.Optional; import java.util.function.Consumer;

How to determine type parameter's variance?

我是研究僧i 提交于 2020-01-01 04:28:06
问题 Inspired by Real-world examples of co- and contravariance in Scala I thought a better question would be: When designing a library, are there a specific set of questions you should ask yourself when determining whether a type parameter should be covariant or contravariant? Or should you make everything invariant and then change as needed? 回答1: Well, simple, does it make sense? Think of Liskov substitution. Co-variance If A <: B , does it make sense to pass a C[A] where a C[B] is expected? If

Kotlin generics: counterintuitive type inference and checking with out keyword

守給你的承諾、 提交于 2019-12-13 15:05:57
问题 I've been recently learning Kotlin, while having some questions with covariant type. The sample code is here. I have Option and Option2 both having a type parameter T and a run extension. I could understand the first two run in validation() , since they are behaved as Java. But why does the third line compile? Option<T> is invariant in T . We cannot passing Option<C> instance into where Option<B> is expected. After I add an out keyword for T , now all of them could compile. Why? open class A

How to determine type parameter's variance?

纵然是瞬间 提交于 2019-12-03 11:36:27
Inspired by Real-world examples of co- and contravariance in Scala I thought a better question would be: When designing a library, are there a specific set of questions you should ask yourself when determining whether a type parameter should be covariant or contravariant? Or should you make everything invariant and then change as needed? Well, simple, does it make sense? Think of Liskov substitution. Co-variance If A <: B , does it make sense to pass a C[A] where a C[B] is expected? If so, make it C[+T] . The classic example is the immutable List , where a List[A] can be passed to anything

Multiple Generics ambiguity

允我心安 提交于 2019-11-30 22:53:43
The codes below are exactly the same, except that one is C# and the other one is VB.Net. C# compiles just fine, but VB.Net throws the warning: Interface 'System.IObserver(Of Foo)' is ambiguous with another implemented interface 'System.IObserver(Of Bar)' due to the 'In' and 'Out' parameters in 'Interface IObserver(Of In T)' Why does VB.Net show the warning and not C#? And most important, how can I resolve this problem? Obs: I'm using .Net Framework 4 with Visual Studio 2010 Ultimate. VB.Net Code: Module Module1 Sub Main() End Sub Public Class Foo End Class Public Class Bar End Class Public

Customizing Autofac's component resolution / Issue with generic co-/contravariance

こ雲淡風輕ζ 提交于 2019-11-30 12:00:28
问题 First, sorry for the vague question title. I couldn't come up with a more precise one. Given these types: { TCommand : ICommand } «interface» «interface» / +-----------+ +----------------------/----+ | ICommand | | ICommandHandler<TCommand> | +-----------+ +---------------------------+ ^ | Handle(command: TCommand) | | +---------------------------+ | ^ | | +------------+ +-------------------+ | FooCommand | | FooCommandHandler | +------------+ +-------------------+ ^ | +-------------------+ |

Why doesn't C# support variant generic classes? [duplicate]

喜你入骨 提交于 2019-11-30 06:18:48
This question already has an answer here: .NET 4.0 Covariance 3 answers Take this small LINQPad example: void Main() { Foo<object> foo = new Foo<string>(); Console.WriteLine(foo.Get()); } class Foo<out T> { public T Get() { return default(T); } } It fails to compile with this error: Invalid variance modifier. Only interface and delegate type parameters can be specified as variant. I don't see any logical problem with the code. Everything can be statically verified. Why is this not allowed? Would it cause some inconsistency in the language, or was it deemed too expensive to implement due to a