Оба кажутся такими же, но на самом деле нет.
Generic версия не будет ЯЩИК ValueType
при передаче где, как не общий вариант требует «бокс»
Вот небольшой пример программы и соответствующий IL, который демонстрирует ситуацию
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()
{
}
}
Ниже соответствующая часть IL генерируется
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
Хотя это вопрос предпочтений, в то время MethodGeneric
является одним WH ич будет работать лучше в случае «типов значений»
Я не понял ваш вопрос. Вы спрашиваете, какая практика лучше? –
Я не думаю, что это имеет реальное значение в этом случае, но я бы сказал, что использование дженериков здесь неоправданно усложняет ситуацию и, вероятно, добавляет накладные расходы на определение функции. – poke
@Saeed Neamati: да, лучшая практика, но, прежде всего, влияние на дизайн, компиляцию, дальнейшая проблема, с которой мы можем столкнуться с тем или иным способом, или, может быть, одно из этих решений ужасно неправильно по какой-то причине я не могу заметить. – Askolein