【问题标题】:C# - Access property in inheriting classC# - 继承类中的访问属性
【发布时间】:2017-09-01 06:07:08
【问题描述】:

我正在尝试访问子类中的泛型类型属性。在下面的示例中,我重新创建了我的问题。是否有解决此问题的方法,或者根本不可能?提前致谢!

编辑:不能将集合声明为 A<Model>A<T>

public abstract class Model {
    public int Id { get; }
}

public interface I<T> where T: Model {
    ICollection<T> Results { get; }
}

public abstract class A { }

public class A<T> : A, I<T> where T : Model {
    public ICollection<T> Results { get; }
}

public class Example {

    A[] col;

    void AddSomeModels() {
        col = new A[] {
            new A<SomeModel>(),
            new A<SomeOtherModel>()
        }
    }

    void DoSomethingWithCollection() {
        foreach (var a in col) {
            // a.Results is not known at this point
            // is it possible to achieve this functionality?
        }
    }
}

【问题讨论】:

  • 它们继承自同一个抽象类(我们称之为AbstractModel)。但不可能将集合声明为A&lt;AbstractModel&gt;。已经试过了。
  • @GoosvandenBekerom 我想我已经解决了你的问题,请看我的回答

标签: c# generics inheritance collections


【解决方案1】:

如果没有妥协,你就无法做你想做的事。

首先,你需要让你的接口I&lt;T&gt;T中协变:

public interface I<out T> where T : Model
{
    IEnumerable<T> Results { get; }
}

因此,第一个折衷方案是T 只能是一个输出。 ICollection&lt;T&gt;T 中不是协变的,因此您需要将 Results 的类型更改为 IEnumerable&lt;T&gt;

执行此操作后,以下内容是类型安全的,因此是允许的:

public void DoSomethingWithCollecion()
{
    var genericCol = col.OfType<I<Model>>();

    foreach (var a in genericCol )
    {
        //a.Results is now accessible.
    }
}

【讨论】:

  • +1 这实际上非常聪明。不过,不知道 OP 对 IEnumerable&lt;T&gt; 替换 ICollection&lt;T&gt; 的感觉如何。
  • 我很乐意做出妥协。这就像一个魅力,谢谢!
最近更新 更多