Is the C# "explicit implementation" of the interface present in Java? - c#

In C#, if you have two base interfaces with the same method (say, F()) you can use explicit implementation to perform different impl. for F(). This alloes you to differently treat the object, corresponding to the current point of view: as IMyInterface1 or IMyInterface2. Is this possible in Java?

No, there's nothing like C#'s explicit interface implementation in Java.
On the plus side, Java has covariant return types, so if you want to provide a more strongly typed implementation than the interface specifies, that's okay. For instance, this is fine:
interface Foo
{
Object getBar();
}
public class Test implements Foo
{
#Override
public String getBar()
{
return "hi";
}
}
C# wouldn't allow that (prior to C# 9, which now supports covariant return types) - and one of the ways around it is typically to implement the interface explicitly and then have a more specific public method (usually called by the interface implementation).

You can achieve similar effect using the mechanism of anonymous interface implementation in Java.
See example:
interface Foo {
void f();
}
interface Bar {
void f();
}
public class Test {
private String foo = "foo", bar = "bar";
Foo getFoo() {
return new Foo() {
#Override
public void f() {
System.out.println(foo);
}
};
}
Bar getBar() {
return new Bar() {
#Override
public void f() {
System.out.println(bar);
}
};
}
public static void main(String... args) {
Test test = new Test();
test.getFoo().f();
test.getBar().f();
}
}

You can only do this if the methods are overloaded.
If you have two method which are expected to do different things, they should have different names IMHO.

No and it should never be present in Java. It's just another bone to throw at people who can't be bothered with good design.
Explicit implementation of an interface should never be needed or used. There are better ways to solver the problem that this tries to solve.

Related

Multiple inheritance from the same interface in C#

Please consider the following program:
using System;
public interface IFoo
{
void DoFoo();
}
public class Bar: IFoo
{
public void DoFoo() => Console.WriteLine("BAR!");
}
public class Baz: Bar, IFoo
{
void IFoo.DoFoo() => Console.WriteLine("baz!");
}
class Program
{
static void Main()
{
Baz baz = new Baz();
baz.DoFoo();
IFoo foo = baz;
foo.DoFoo();
Bar bar = baz;
bar.DoFoo();
IFoo foobar = bar;
foobar.DoFoo();
}
}
It gives the following output which I personally with my C++ background consider highly unexpected:
BAR!
baz!
BAR!
baz!
Having , IFoo in the declaration of Baz seems to be substantial, because otherwise void IFoo.DoFoo() doesn't compile.
Can someone please explain what is going on here (especially the last line)? And what should be done to prevent such behavior in real life? Should one avoid implementing from the same interface at all or there are some other rules to avoid problems?
UPD:
Looks like the principal problem here is not with "multiple inheritance" (which is not real multiple inheritance actually), but with the way interface methods can be implemented in C#. Namely, one can have two different implementations of the same method in the same class, one of which is explicit, another is implicit. E.g. this program:
using System;
public interface IFoo
{
void DoFoo();
}
public class Bar: IFoo
{
void IFoo.DoFoo() => Console.WriteLine("Foo!");
public void DoFoo() => Console.WriteLine("BAR!");
}
class Program
{
static void Main()
{
Bar baz = new Bar();
baz.DoFoo();
IFoo foo = baz;
foo.DoFoo();
}
}
prints
BAR!
Foo!
The trick with "multiple inheritance" just allows to introduce the explicit implementation from a derived class.
From my point of view this feature of C# is potentially dangerous, because if one implements a method of an interface, one usually expects the same method will be called no matter if it is invoked from the interface or from the class. And this is really the case if one implements everything only explicitly or only implicitly. But if both ways are used, this assumption is broken. So the moral seems to be:
Don't mix implicit and explicit implementation of the same method if you don't have in mind to employ this strange effect for some purpose.
Use explicit implementation in derived classes with caution.
This is a difference in the explicit implementation (void IFoo.DoFoo()) vs the implicit implementation (public void DoFoo()). The compiler will use the explicit implementation first. If you provide both an explicit and implicit implementation then the difference becomes clear:
https://dotnetfiddle.net/7l9gIs
using System;
public interface IFoo
{
void DoFoo();
}
public class Bar: IFoo
{
public void DoFoo(){ Console.WriteLine("BAR!"); }
}
public class Baz: Bar, IFoo
{
void IFoo.DoFoo(){ Console.WriteLine("baz explicit!"); }
public new void DoFoo(){ Console.WriteLine("baz implicit!"); }
}
public class Program
{
public static void Main()
{
Baz baz = new Baz();
baz.DoFoo();
IFoo foo = baz;
foo.DoFoo();
Bar bar = baz;
bar.DoFoo();
IFoo foobar = bar;
foobar.DoFoo();
}
}
Output
baz implicit!
baz explicit!
BAR!
baz explicit!
Implicit implementations tend to be more common and more convenient for usage. They are less verbose and any usage of the concrete type will have the implementations of the members exposed. Implicit implementations don't include the name of the interface being implemented before the member name, so the compiler infers this. The members will be exposed as public and will be accessible when the object is cast as the concrete type.
Visit this link for more details https://www.pluralsight.com/guides/distinguish-explicit-and-implicit-interface-implementation-csharp
The confusion is starting when you implement Baz from IFoo. Because Bar is already implements IFoo and Baz is the subclass of Bar. So, you dont need to do that.
In object oriented programming its not a best practice, in fact it is worst practice.
If you want to override DoFoo method, use the following code
public interface IFoo
{
void DoFoo();
}
public class Bar : IFoo
{
public virtual void DoFoo()
{
// do something
}
}
public class Baz : Bar
{
public override void DoFoo()
{
// override what you did in Bar class
}
}
In your code, when you try to baz.DoFoo, in fact you are calling bar.DoFoo.Because you didnt override it. Its the problem.

How can a class inherit from a parameterized version of itself?

I saw a C# class SomeClass that was defined like
public class SomeClass : IComparable<SomeClass>, IEquatable<SomeClass>
{
// ...
}
and I'm wondering how to translate that into English. The way I understand it seems logically impossible. How can a class inherit from a parameterized version of itself? Also, is this a common design pattern?
The key is to recognize that it's not inheriting from (or implementing) a parameterized version of itself, but rather inheriting from (or implementing) another class or interface, and using itself as a generic parameter for that target type.
For example, IComparable<T> says that there will be a CompareTo() method that takes an object of type T as a parameter. So by implementing IComparable<SomeClass> you're simply guaranteeing that a method with that signature will exist on this class:
public class SomeClass : IComparable<SomeClass>
{
public int CompareTo(SomeClass other)
{
//...
}
}
And yes, this is fairly common practice. Classes often implement the generic IComparable<> and IEquatable<> interfaces to show that they can be compared with other items of the same type. It's maybe also worth mentioning that enums in Java are declared as extending Enum<> of themselves--a pattern which is not common in C#, but does appear from time to time.
Translated in "English" it means: "Boy (or girl), you'd better be type-safe when implementing those interfaces, especially IComparable. Otherwise, you'll have to perform type casting, which I guess you don't want"
See the code below. SomeClass implemented IComparable and IComparable.
See differencies between implementations of CompareTo(object) and CompareTo(SomeClass).
namespace InterfacesStuff
{
internal class Program
{
private static void Main(string[] args)
{
var someClass1 = new SomeClass {ComparedValue = 1};
var someClass2 = new SomeClass {ComparedValue = 2};
//someClassObject defined as SomeClass
//object someClassObject = new SomeClass { ComparedValue = 2 };
//someClassObject defined as anything else but SomeClass
object someClassObject = 5;
int comparisonSomeClassBySomeClass = someClass1.CompareTo(someClass2);
int comparisonSomeClassByObject = someClass1.CompareTo(someClassObject);
}
}
public class SomeClass : IComparable, IComparable<SomeClass>, IEquatable<string>, IEquatable<int>,
IEquatable<double>
{
public int ComparedValue;
public int CompareTo(object obj)
{
var presumedSomeClassObject = obj as SomeClass;
if (presumedSomeClassObject != null)
{
if (ComparedValue <= ((SomeClass) obj).ComparedValue)
return -1;
}
return 0;
}
public int CompareTo(SomeClass other)
{
if (ComparedValue <= other.ComparedValue)
return -1;
return 0;
}
public bool Equals(double other)
{
throw new NotImplementedException();
}
public bool Equals(int other)
{
throw new NotImplementedException();
}
public bool Equals(string other)
{
throw new NotImplementedException();
}
}
}
It is not Inheriting, It is implementing the IComparable Interface. what is going on is
Someclass Implements the Icomparable and the IEquatable interface. Implementing an interface is like signing a contract stating you gaurentee that this class will implement the methods on an interface.
Icomparable msdn, IEquatable. If you look at the MSDN pages you can see that SomeClass gaurentees it will implement the methods in some fashion.
This is very common practice and it is many different names. The ones I hear most are programming by contract and Implementation over Inhertience. It lets you do a lot of cool things, like Dependency Injection, Proper Unit testing, better Generics. It does this because the compiler doesnt need to know the concrete class that your object is implementing. It just needs to know that it has certain functions on it. For further reading on this I would read Chapter one of the gang of four Design pattern book.
Wikipedia link Specifically the Introduction to Chapter one section
It doesn't really have to be convenient to express it in english for it to be valid code, although I'd probably read that as "SomeClass is comparable and equatable to itself". That doesn't really explain what's going on though, it's just a way of expressing it.
In C# types can be generic over categories of other types. Generic types are basically "type constructors". They take other types as parameters, and use them to construct new types. For instance, IEnumerable<int> and IEnumerable<string> are two completely different types. The non-generic version (IEnumerable) is a third one. In C# a type A can inherit ANY other type B as long as none of the following is true (I hope I didn't miss anything):
B is already a subtype of A
B is a class and A has already inherited another class
B is a struct
A is an interface but B is not
A is the same type as B
B is sealed
A is a struct and B is not an interface
This even makes the following code legal:
class Foo<T>
{
public T Value;
}
class Foo : Foo<int>
{
}
Foo and Foo<T> are different types, so there's no problem at all for one to inherit the other.
You can read more about generics here:
https://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx
And about inheritance here:
https://msdn.microsoft.com/en-us/library/ms173149.aspx
The code you posted does not inherit from any class. It is implementing certain so-called Interfaces. How to translate that snippet: "I guarantee that SomeClass will be Comparable and equatable with other SomeClass instances. I will provide definitions in this class on how to do that."
About specializing a class from some other class...
What you can do is something like this:
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Pet
{
protected string name;
public Pet(String name)
{
this.name = name;
}
}
class Dog : Pet
{
private List<String> tricks;
public Dog(String name, List<String> tricks):base(name)
{
this.tricks = tricks;
}
}
class Program
{
static void Main(string[] args)
{
List<string> tricks = new List<string>();
tricks.Add("sit");
tricks.Add("jump");
tricks.Add("bark");
Dog puppy = new Dog("Fido", tricks);
}
}
}
Dog inherits from Pet. Dog calls Pet's constructor at creation. Whatever name you pass into Dog constructor, it will forward it to Pet constructor.
Because what happens is that a subclass first calls the constructor of its superclass with the appropriate arguments. Then it runs its own constructor. Whatever is declared as public or protected in a class will be visible to its subclasses.
Therefore Dog will have name and also a list of tricks:
You achieve this kind of view with the "Locals" window.
I recommend that you read some tutorials on c# inheritance, interfaces and generics

What is the nicest way to dynamically implement an interface in C#?

I often find it quite a distraction to have to implement an interface just because I need it once for some method call. I have to create a class somewhere else, implement the interface etc. etc.
Java has a feature called Anonymous Classes that allows one to implement the interface "inline". My question is thus: what is the nicest way you can think of of accomplishing something similar in C# using existing syntax (and I realise that "nicest" is subjective). I'm looking for nice syntax, not necessarily performance.
I implemented the following as POC in C#:
Given
interface IFoobar
{
Boolean Foobar(String s);
}
IFoobar foo = Implement.Interface<IFoobar>(new {
Foobar = new Func<String, Boolean>(s => s == "foobar")
});
This uses an anonymous object and some reflection/emit to implement the IFoobar interface (overlooking properties, generic methods and overloading). But, I'm not a fan of the new Func<...> stuff but can't do without.
Looking around I noticed a library called Impromptu Interface, but wasn't impressed by its syntax to support methods.
Is there a "nicer" way?
Edit: I'm not looking for Java vs C# flame wars.
You mentioned that you didn't need to do this often, don't care about performance, and usually want to do it during unit testing. Why not use a mocking framework?
For example, using the Moq library as an example:
public interface IFoobar {
Boolean Foobar(String s);
}
void Main() {
var foo = new Mock<IFoobar>();
foo.Setup(x => x.Foobar(It.IsAny<string>()))
.Returns((string s) => s == "foobar");
foo.Object.Foobar("notbar"); // false
foo.Object.Foobar("foobar"); // true
}
Take a look at "impromptu-interface" (https://github.com/ekonbenefits/impromptu-interface).
It will allow you to do something like...
class Program
{
static void Main(string[] args)
{
Bar b = new Bar();
b.DoSomethingWithFoo(new
{
Foobar = Return<string>.Arguments<string>(r => "foo")
}.ActLike<IFoo>());
}
}
public interface IFoo
{
string Foobar(String s);
}
public class Bar
{
public void DoSomethingWithFoo(IFoo foo)
{
Console.WriteLine(foo.Foobar("Hello World"));
}
}
A good way to do what you need in C# could be using Clay objects:
public interface IFoobar{
Func<string, bool> Foobar { get; set; }
}
With that interface you can do something like this:
dynamic New = new ClayFactory();
var foobar= New.FooBar();
foobar.Foobar = new Func<string, bool>(s => s == "foobar");
// Concrete interface implementation gets magically created!
IFoobar lou = foobar;
var result =lou.Foobar("foo");// return false
What makes the magic possible is that Clay is overriding the cast operator and creating a dynamic proxy for the interface (using Castle) that delegates the members to the Clay object.
Another way could be using the Impromptu Interface library which lets you wrap any object with an interface. That means any objects now can have dynamic behaviors. If an object has interface methods, you can directly attach behaviors to them as needed. If an object does not have interface methods, you define an interface and wrap the object in it, then, attach behaviors to the interface methods as needed.This library is an automatic way of applying the Object Adapter pattern.
If you have an interface like this:
public Interface IFoobar
{
bool Foobar(string s);
}
You can decorate an anonymous type as I show below:
//Anonymous Class
var anon = new {Foobar= Return<bool>.Arguments<string>(s => s == "foobar")};
var myInterface = anon.ActLike<IFoobar>();
Or you could use an ExpandoObject too:
dynamic expando = Build<ExpandoObject>.NewObject(Foobar: Return<bool>.Arguments<string>(s => s == "foobar"));
IMyInterface myInterface = Impromptu.ActLike(expando);
If you want to implement more than one interface, check my answer in this post.
public class Foo
{
public Func<string,bool> TheDelegate {get;set;}
}
public class Bar
{
public bool Implementation(string s)
{
return s == "True";
}
}
public class Usage
{
var myBar = new Bar();
var myFoo = new Foo { TheDelegate = myBar.Implementation };
//Or
var myFoo = new Foo { TheDelegate = x => x == "True" };
//This removes the need for Bar completely
}
As you can see in the above example, java-like hacks are completely unneeded in C#, which is a much better language.
It is possible to do a cleaner lambda syntax, however at the expense of static type checking inside Create().
I was able to use ImpromptuInterface to do this:
IFoobar foo = Implement.Interface(new {
Foobar = Function.Create(s => s == "foobar"),
});
By creating the following classes:
public static class Implement{
public static dynamic Interface(object source){
return Impromptu.ActLike(source);
}
}
public static class Function{
public static Func<dynamic> Create(Func<dynamic> del){
return del;
}
public static Func<dynamic,dynamic> Create(Func<dynamic,dynamic> del){
return del;
}
public static Func<dynamic,dynamic,dynamic> Create(Func<dynamic,dynamic, dynamic> del){
return del;
}
public static Func<dynamic,dynamic,dynamic,dynamic> Create(Func<dynamic,dynamic, dynamic,dynamic> del){
return del;
}
//...Add more if you want
}
Unfortunately anonymous classes in C# canĀ“t implement interfaces as in Java. However you can create some kind of adapter-class without any additional dependencies on external projects. Just create a base-class that implements your interface using a Func:
interface IFoo
{
bool DoSomething(string value);
}
class Bar : IFoo
{
private readonly Func<string, bool> m_DoSomething;
public Bar(Func<string, bool> DoSomething) { this.m_DoSomething = DoSomething; }
public bool DoSomething(string value)
{
return this.m_DoSomething(value);
}
}
Now you can call it like this:
var result = new Bar(x => true);
Or also using named arguments which is bit more obvious, in particular if your interface has more then one method:
var result = new Bar(DoSomething: x => true);
Only drawback is that you need an implementing class for every interface you have. Thus this approach is only usefull if you want to implement every interface more than once with different behaviour. So whenever I need different implementations for the same interface I use this approach.
If your biggest complaint is implementing the interface somewhere else, why not create a nested class directly before/after your method? (Compare to a Java static nested class.)
That's more idiomatic C# than creating/using some dynamic framework.

C# interface cannot contain operators

Can anyone please explain why C# interfaces are not allowed to contain operators?
Thanks.
C# operators have to be static. Interfaces, by definition, apply to instances. There is no mechanism to require a type to implement static members.
EDIT:
Since C# 8.0, as you can see here, it is now possible to define local methods in interfaces and implement them within the interface itself, e.g. allowing to create method overloads without requiring implementations to care about those overloads as well, when they might just supply an additional parameter to the overload that has to be implemented.
Along with this, you can also define operators within interfaces, though they must be static and so they must be implemented in the interface.
So in C# 8.0 this will print "this works in C# 8" followed by "1":
interface ICanAdd
{
int Value { get; }
public static int operator+ (ICanAdd lvalue, int rvalue)
{
Console.WriteLine("this works in C# 8");
return lvalue.Value + rvalue;
}
}
class Add : ICanAdd
{
public int Value => 0;
}
class Program
{
static void Main(string[] args)
{
ICanAdd foo = new Add();
var x = foo + 1;
Console.WriteLine(x);
}
}
Edit 2020-01-23
You cannot add conversion, equality or inequality operators to interfaces, otherwise you'll hit the following error:
CS0567 C# Interfaces cannot contain conversion, equality, or inequality operators
You can't define operators on interfaces because a class can implement multiple interfaces. Imagine if this code were possible:
static class Fooness {
public static operator==(IFoo l, IFoo r) { ... }
}
static class Barness {
public static operator==(IBar l, IBar r) { ... }
}
public class Foobar : IFoo, IBar { ... }
Which == implementation should prevail if used on instances of Foobar? (And before you answer, imagine if IFoo/Fooness come from one DLL and IBar/Barness comes from another).
Even if you could somehow resolve that ambiguity, we should ask ourselves whether it would even be a good idea. I hope the above shows that with operator== it's a seriously bad idea. The author of the per-interface == operator presumes that the only important aspects of an object when it comes to comparison are those encompassed by the interface. Sometimes that can be true, but it's not generally true.
That's why it's prudent to only use operators on sealed classes. Only then can you be sure that your operator knows enough about the object to work correctly.
If your method could not be properly implemented on the interface, you can make a call to a self method that will be overriden by the derived class:
public interface INotification
{
INotification Combine(INotification b);
public static INotification operator +(INotification a, INotification b)
{
return a.Combine(b);
}
}
Derived class:
public class Notification : INotification
{
public INotification Combine(INotification b)
{
_events.AddRange(b.Events);
_logs.AddRange(b.Logs);
ValidationResult.Errors.AddRange(b.GetValidationErrors());
return this;
}
public static Notification operator +(Notification a, Notification b)
{
a._events.AddRange(b.Events);
a._logs.AddRange(b.Logs);
a.ValidationResult += b.ValidationResult;
return a;
}
}

Is it possible to specify a generic constraint for a type parameter to be convertible FROM another type?

Suppose I write a library with the following:
public class Bar { /* ... */ }
public class SomeWeirdClass<T>
where T : ???
{
public T BarMaker(Bar b)
{
// ... play with b
T t = (T)b
return (T) b;
}
}
Later, I expect users to use my library by defining their own types which are convertible to Bar and using the SomeWeirdClass 'factory'.
public class Foo
{
public static explicit operator Foo(Bar f)
{
return new Bar();
}
}
public class Demo
{
public static void demo()
{
Bar b = new Bar();
SomeWeirdClass<Foo> weird = new SomeWeirdClass<Foo>();
Foo f = weird.BarMaker(b);
}
}
this will compile if i set where T : Foo but the problem is that I don't know about Foo at the library's compile time, and I actually want something more like where T : some class that can be instantiated, given a Bar
Is this possible? From my limited knowledge it does not seem to be, but the ingenuity of the .NET framework and its users always surprises me...
This may or not be related to the idea of static interface methods - at least, I can see the value in being able to specify the presence of factory methods to create objects (similar to the same way that you can already perform where T : new())
edit: Solution - thanks to Nick and bzIm - For other readers I'll provide a completed solution as I understand it:
edit2: This solution requires Foo to expose a public default constructor. For an even stupider better solution that does not require this see the very bottom of this post.
public class Bar {}
public class SomeWeirdClass<T>
where T : IConvertibleFromBar<T>, new()
{
public T BarMaker(Bar b)
{
T t = new T();
t.Convert(b);
return t;
}
}
public interface IConvertibleFromBar<T>
{
T Convert(Bar b);
}
public class Foo : IConvertibleFromBar<Foo>
{
public static explicit operator Foo(Bar f)
{
return null;
}
public Foo Convert(Bar b)
{
return (Foo) b;
}
}
public class Demo
{
public static void demo()
{
Bar b = new Bar();
SomeWeirdClass<Foo> weird = new SomeWeirdClass<Foo>();
Foo f = weird.BarMaker(b);
}
}
edit2: Solution 2: Create a type convertor factory to use:
#region library defined code
public class Bar {}
public class SomeWeirdClass<T, TFactory>
where TFactory : IConvertorFactory<Bar, T>, new()
{
private static TFactory convertor = new TFactory();
public T BarMaker(Bar b)
{
return convertor.Convert(b);
}
}
public interface IConvertorFactory<TFrom, TTo>
{
TTo Convert(TFrom from);
}
#endregion
#region user defined code
public class BarToFooConvertor : IConvertorFactory<Bar, Foo>
{
public Foo Convert(Bar from)
{
return (Foo) from;
}
}
public class Foo
{
public Foo(int a) {}
public static explicit operator Foo(Bar f)
{
return null;
}
public Foo Convert(Bar b)
{
return (Foo) b;
}
}
#endregion
public class Demo
{
public static void demo()
{
Bar b = new Bar();
SomeWeirdClass<Foo, BarToFooConvertor> weird = new SomeWeirdClass<Foo, BarToFooConvertor>();
Foo f = weird.BarMaker(b);
}
}
Sounds like you found a solution to the larger problem. To answer your specific question: no, neither C# nor the CLR support the "backwards" generic type parameter constraint. That is,
class C<T> where Foo : T
"T must be Foo or a type which Foo converts to" is not supported.
There are languages that have that sort of constraint; IIRC Scala is such a language. I suspect this feature would be handy for certain uses of contravariant interfaces.
I don't think there is necessarily a syntactically cool way to do this built into the language. One possible solution to your problem could be to define a convertible interface:
public interface IConvertible<T>
where T : new() // Probably will need this
{
T Convert();
}
Then your class could be:
public class Foo : IConvertible<Bar>
{
}
I think this gets you close to where you want to be... All the Foo's and Bar's in your question sometimes make it hard to determine exactly what your intent is. Hope this helps.
Edit: Added where constraint... you will probably have to be able to create a new instance in your convertible class.
Edit 2: Made Foo inherit from ICovertible<Bar>
You could make a detour via an interface which is used as a type constraint.
For example, where T : IComparable<U> is used to constrain the type to something that can be compared to another thing, which must express this ability by implementing IComparable<another>. If you had an interface ICastableFrom<T>, you could achieve what you want by forcing them to implement ICastableFrom<Bar>.
Rather than go through the trouble of defining an interface and modifying your class to implement that interface, why not just do this?
public class SomeWeirdClass<T>
{
// aside: why is this method called 'BarMaker' if it returns a T?
public T BarMaker(Bar b, Func<Bar, T> converter)
{
// ... play with b
return converter(b);
}
}
Then in the event that you are dealing with an object of a type T to which Bar can be directly cast, this method could be called simply as follows:
var someWeirdObject = new SomeWeirdClass<Foo>();
var someBar = new Bar();
var someFoo = someWeirdObjcet.BarMaker(someBar, bar => bar as Foo);
By the way (since the Func<T, TResult> delegate emerged in .NET 3.5), you could also use Converter<TInput, TOutput> (which is exactly the same) for the converter parameter.

Categories

Resources