What are the arguments to use one or another of those two method implementations (in Example class)?
public interface IInterface
{
void DoIt();
}
public class Example
{
public void MethodInterface(IInterface arg)
{
arg.DoIt();
}
public void MethodGeneric<T>(T arg) where T: IInterface
{
arg.DoIt();
}
}
PS: If method returns an IInterface or T I would choose the "generic" way to avoid further casting in type T if needed.
A parameterized type is an instantiation of a generic type with actual type arguments. A generic type is a reference type that has one or more type parameters. These type parameters are later replaced by type arguments when the generic type is instantiated (or declared ).
Java Generic Classes and Subtyping We can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses.
It's often useful to define interfaces either for generic collection classes, or for the generic classes that represent items in the collection. To avoid boxing and unboxing operations on value types, it's better to use generic interfaces, such as IComparable<T>, on generic classes.
You can declare variant generic interfaces by using the in and out keywords for generic type parameters. ref , in , and out parameters in C# cannot be variant. Value types also do not support variance. You can declare a generic type parameter covariant by using the out keyword.
Both appears to be same, but really not.
Generic version will not box the ValueType
when passed where as non generic version requires "boxing"
Here is a small sample program and relevant IL which demonstrates the situation
void Main()
{
Example ex = new Example();
TestStruct tex = new TestStruct();
ex.MethodGeneric(tex);
ex.MethodInterface(tex);
}
public interface IInterface
{
void DoIt();
}
public class Example
{
public void MethodInterface(IInterface arg)
{
arg.DoIt();
}
public void MethodGeneric<T>(T arg) where T : IInterface
{
arg.DoIt();
}
}
internal struct TestStruct : IInterface
{
public void DoIt()
{
}
}
Below is the relevant part of IL generated
IL_0001: newobj UserQuery+Example..ctor
IL_0006: stloc.0 // ex
IL_0007: ldloca.s 01 // tex
IL_0009: initobj UserQuery.TestStruct
IL_000F: ldloc.0 // ex
IL_0010: ldloc.1 // tex
IL_0011: callvirt UserQuery+Example.MethodGeneric
IL_0016: nop
IL_0017: ldloc.0 // ex
IL_0018: ldloc.1 // tex
IL_0019: box UserQuery.TestStruct //<--Box opcode
IL_001E: callvirt UserQuery+Example.MethodInterface
Though it is a matter of preference, While MethodGeneric
is the one which will perform better in case of "ValueTypes"
I suggest passing Interface as a simple parameter, instead of using generic approach, for these reasons:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With