Вызовите метод с ковариантным универсальным типом, указанным в предоставленном параметре - PullRequest
2 голосов
/ 20 марта 2011

Ключевое слово out ниже (как я не знал, но по причинам, которые могут быть для вас очевидны) недопустимо:

public static class DataExtensions {
    public static void ReplaceAll<T>(this EntityCollection<T> collectionToReplace, IEnumerable<T> collectionToAdd) where T : EntityObject {
        RemoveEach(collectionToReplace);
        foreach (T item in collectionToAdd) collectionToReplace.Add(item);
    }

    public static void RemoveEach(this EntityCollection<out EntityObject> collectionToEmpty) {
        if (!collectionToEmpty.IsLoaded) collectionToEmpty.Load();
        while (collectionToEmpty.Any()) collectionToEmpty.Remove(collectionToEmpty.First());
    }
}

и без него RemoveEach(collectionToReplace); имеет несоответствие параметров:

Argument 1: cannot convert from 'System.Data.Objects.DataClasses.EntityCollection<T>' to 'System.Data.Objects.DataClasses.EntityCollection<System.Data.Objects.DataClasses.EntityObject>'

То же самое при вызове с определенным (неуниверсальным) производным типом. Нужно ли использовать следующую подпись?

public static void RemoveEach<T>(this EntityCollection<T> collectionToEmpty) where T : EntityObject {

Если это так, intellisense или компилятор должны предупредить меня об использовании абстрактного класса в качестве универсального спецификатора типа в этом методе, потому что я только что создал не вызываемый метод, нет? И если вы не возражаете, не могли бы вы указать, почему это так (например, сценарий, в котором безопасность типов будет нарушена или возникнет путаница, если это будет разрешено).

Спасибо, Шеннон

1 Ответ

2 голосов
/ 20 марта 2011

Вы должны просто иметь возможность использовать:

public static void RemoveEach<T>(this EntityCollection<T> collectionToEmpty)
    where T : class
{
    if (!collectionToEmpty.IsLoaded) collectionToEmpty.Load();
    while (collectionToEmpty.Any()) collectionToEmpty.Remove(collectionToEmpty.First());
}

Это единственное ограничение, которое требуется EntityCollection<T>, и вы не используете ничего в теле метода, для которого требуется EntityObject.

Кстати, чем ты здесь занимаешься? collectionToEmpty.Clear()?Я давно не пользовался EF, так что это не совсем очевидно ...

...