2016-03-31 6 views
4

Я хочу знать, почему это ошибка компиляции, чтобы лучше понять язык C#.C# почему я не могу передать «базовый» интерфейс по ссылке?

В моем коде у меня есть интерфейс (IMyInterface), который происходит из IDisposable. У меня есть другой метод, который принимает параметр типа 'ref IDisposable'. Но я не могу передать член var типа IMyInterface этому методу. Вот мой пример кода ниже:

using System; 

namespace CompileErrorBaseInterface 
{ 
    public interface IMyInterface : IDisposable { } 

    class Program 
    { 
     private IMyInterface _myInterfaceObj; 

     static void Main(string[] args) { } 

     public void ExampleMethod() 
     { 
      MyMethodBaseInterface(ref _myInterfaceObj); //compile error 
      MyMethodDerivedInterface(ref _myInterfaceObj); //no compile error 
     } 

     private void MyMethodBaseInterface(ref IDisposable foo) { } 

     private void MyMethodDerivedInterface(ref IMyInterface foo) { } 
    } 
} 

Ошибки компиляции являются:

  • Аргумент 1: не удается преобразовать из «исх CompileErrorBaseInterface.IMyInterface» к «исх System.IDisposable» Лучший перегруженный метод матч за
  • 'CompileErrorBaseInterface.Program.MyMethodBaseInterface (исх System.IDisposable)' имеет некоторые недопустимые аргументы

Может ли кто-нибудь объяснить, почему это не разрешено или невозможно для компилятора? У меня есть обходное решение с использованием дженериков, поэтому я просто хочу понять, почему так не разрешено делать это.

Спасибо.

ответ

7

Рассмотрим следующий пример:

private void MyMethod(ref IDisposable foo) 
{ 
    // This is a valid statement, since SqlConnection implements IDisposable 
    foo = new SqlConnection(); 
} 

Если вы разрешили передать IMyInterface в MyMethod, вы имеете проблему, так как вы просто присвоен объект типа SqlConnection (который не реализует IMyInterface) к переменной типа IMyInterface.

Для получения более подробной информации, посмотрите на следующую запись в блоге о C# гуру Эрик Липперт: