c# object interface return 类型协变

c# object interface return type covariance

C# 编译器:

错误 CS0738:Field<T>' does not implement interface memberField.Value.get' 和最佳实施候选 Field<T>.Value.get' return typeT' 不匹配接口成员 return 类型 `object'

public interface Field
{
   object Value {get;}
}

public class MyField<T> : Field
{
   T _value;
   public T Value
   {
      get
      {
         return _value;
      }
   }
}

为什么? List < T > extends List in microsoft 类,但我作为用户(复制相同的设计模式)不允许这样做吗?为什么?

尝试 where T: object 也会给出编译器错误...

我该如何解决这个问题?

关于同一主题的其他 1.000.000 个线程,说:
blablabla, 'return type covariance', blablabla, 'you cant'.

他们没有提出关于如何编译这个野兽的解决方案或变通方法。 要求:
1) Field 是一个不能采用泛型的接口。名为 "unity" 的邪恶框架禁止泛型。
2) "implements Field" 具有通用 T.

的字段 < T >

您不在界面中使用模板类型,而是object.Try这样:

 interface Field<T>
    {
        T Value { get; }
    }

public class MyField<T> : Field<T>
    {
        private T _value;
        public T Value
        {
            get
            {
                return _value;
            }
        }
    }
public Object Value
   {
      get
      {
         return _value;
      }
   }

可能您需要这个。由于每种数据类型都继承 Object 但反之则不然。我想这就是为什么协方差问题来了。

我不确定这是否正是您想要的。但是,如果您的界面不能通用,那么这就是可行的。

public interface Field
{
   object Value {get;}
}

public class MyField<T> : Field
{
   public T _value;

   public T MyTypedValue
   {
       get 
       { 
           return _value; 
       }
   }

   public object Value
   {
       get
       {
          return _value;
       }
   }
}

您可以显式实现接口。 https://msdn.microsoft.com/en-us/library/ms173157.aspx

相同的模式用于 IEnumerable 的非通用版本和通用的 IEnumerable<T>

你也可以做同样的事情,也有通用接口。

public interface Field
{
    object Value { get; }
}

public interface Field<T> : Field
{
    new T Value { get; }
}

public class MyField<T> : Field<T>
{
    public T Value { get; } // generic

    object Field.Value => Value; // non generic
}

现在手头有Field<T>就可以愉快地使用T了。如果你有 Field 你得到值的对象形式 T

public class Field<T> : Field
{
   T _value;

   //specific interface implementation
   object Field.Value
   {
     get
     {
        return _value;
     }
   }

   public T Value
   {
      get
      {
         return _value;
      }
   }
}