Есть ли разница между:
public void Method1<T>(class1 c, T obj) where T:Imyinterface
и
public void Method2(class1 c, Imyinterface obj)
?
В чем преимущества первого метода?
Есть ли разница между:
public void Method1<T>(class1 c, T obj) where T:Imyinterface
и
public void Method2(class1 c, Imyinterface obj)
?
В чем преимущества первого метода?
В то время как в вашем сценарии это практически одно и то же (за исключением того факта, что с помощью метода, принимающего параметр интерфейса, он будет преобразовывать конкретный объект в тип интерфейса) рассмотрим несколько иной сценарий. Скажем, мы хотим, чтобы наш метод принимал только класс, который реализует два интерфейса IMyInterface1
и IMyInterface2
, и что в противном случае код не должен компилироваться:
interface IMyInterface1 { }
interface IMyInterface2 { }
class MyClass : IMyInterface1 { }
public void Method1<T>(Class1 c, T obj) where T : IMyInterface1, IMyInterface2
{
}
Если мы создадим метод, который принимает интерфейс в качестве второго параметра, он не будет удовлетворять условию, поскольку он не ограничивает пользователя отправкой экземпляра класса, который реализует только один интерфейс, но не реализует второй интерфейс, такой как для MyClass и IMyInterface2 в этом примере.
А какой интерфейс следует отправить пользователю? Он действительно не знает тип, который нужно отправить во время компиляции.
Это хорошее место для использования общих и общих ограничений, а с другой стороны, мы не можем использовать один параметр интерфейса.
Использование общего метода дает вам различные возможности с небольшими изменениями подписи:
public void Method1<T>(class1 c, T obj) where T:Imyinterface, new()
: public T Method1<T>(class1 c, T obj) where T:Imyinterface
: public void Method1<T>(class1 c, ref T obj) where T:Imyinterface
: obj
. То же самое относится к out
.Это невозможно в не общей версии.
Как уже отмечалось, с помощью недействительных методов разница в использовании невелика.
Если вы посмотрите за кулисами, вы увидите, что с помощью общего метода .NET будет компилировать отдельный метод для каждого типа, с которым вы его вызываете. Это позволяет избежать бокса при вызове с помощью структуры.
Большая разница возникает, когда вы используете возвращаемый тип.
public T Method1<T>(class1 c, T obj) where T: IMyInterface
и
public IMyinterface Method2(class1 c, IMyInterface obj)
В стандартной версии вы возвращаете исходный тип, чтобы продолжить использовать свойства или методы (экземпляр или расширение) в исходном типе.
В версии, отличной от общего, вы возвращаете значение типа IMyInterface
, поэтому вы можете вызывать только свойства или методы, которые являются частью IMyInterface
.
Это наиболее интересно, в моей книге, при использовании с методами расширения и API в свободном стиле.
public static T Move<T>(this T animal) where T : ICanMove
{
return animal;
}
public static T Fly<T>(this T animal) where T : ICanFly
{
return animal;
}
public static T Pounce<T>(this T animal) where T : ICanPounce
{
return animal;
}
Учитывая, что Tiger реализует ICanMove и ICanPounce, а Eagle реализует ICanMove и ICanFly, я могу вызвать вышеупомянутые методы расширения, применимые к исходному типу. Intellisense покажет .Fly() и .Move() для орла и .Pounce() и .Move() для тигра.
var birdie = new Eagle();
birdie
.Move()
.Fly()
.Move()
.Fly();
var kitty = new Tiger();
kitty
.Move()
.Pounce()
.Move()
.Pounce();
Вот как это выглядело бы, если бы вы внедрили Move в основном:
public static ICanMove Move<T>(this ICanMove animal)
{
return animal;
}
Поскольку интерфейс ICanMove возвращается, компилятор не знает, что он изначально был Eagle или Tiger, поэтому вы можете использовать только расширения, методы или свойства, которые являются частью интерфейса ICanMove.
Для методов void
нет большой разницы.
public void Method1<T>(class1 c, T obj) where T : Imyinterface
равно
public void Method2(class1 c, Imyinterface obj, Type t)
где t
должно быть Imyinterface
.
Итак, если вам нужно передать некоторый Type
вашему методу, и вам нужно применить некоторые ограничения к этому Type
во время компиляции, используйте общий метод.