【问题标题】:Replace a base class with a concrete implementation C#用具体实现 C# 替换基类
【发布时间】:2013-10-06 01:36:27
【问题描述】:

我有以下抽象类和接口:

public interface ITypedEntity{
    TypedEntity Type { get; set; }
}

public abstract class TypedEntity:INamedEntity{
    public abstract int Id{get;set;}
    public abstract string Name { get; set; }
}

但是当我尝试创建一个实现 ITypedEntity 并具有 TypedEntity 的具体实现的类时,我收到以下错误

 Magazine does not implement interface member ITypedEntity.Type. Magazine.Type cannot implement 'ITypedEntity.Type' because it does not have the matching return type of 'TypedEntity'

我的具体实现代码如下

public class Magazine:INamedEntity,ITypedEntity
{
    public int Id {get;set;}
    [MaxLength(250)]
    public string Name {get;set;}
    public MagazineType Type { get; set; }
}
public class MagazineType : TypedEntity
{
    override public int Id { get; set; }
    override public string Name { get; set; }
}

我想我明白发生了什么,但我不知道为什么,因为 MagazineType 是一个 TypedEntity。

谢谢。

更新 1 我不得不提一下,我想将这些类与 EF CodeFirst 一起使用,并且我想为每个实现 ITypedEntity 的类创建一个不同的表。

【问题讨论】:

  • MagazineType 是 TypedEntity 但 TypedEntity 不是 MagazineType。也许你可以定义你的界面,比如ITypedEntity Type { get; set; }
  • 但是引用 Magazine 的代码存储在 ITypedEntity 类型的变量中可能会尝试将 不是 MagazineType 的内容存储到 @ 987654328@财产。
  • Magazine.Type的返回类型改为EntityType。它仍然可以是MagazineType 的实例,但签名必须匹配以满足接口实现。

标签: c# asp.net entity-framework oop


【解决方案1】:

要实现这一点,您必须添加 explicit implementationITypedEntity.Type

public class Magazine:INamedEntity,ITypedEntity
{
    public int Id {get;set;}
    [MaxLength(250)]
    public string Name {get;set;}
    public MagazineType Type { get; set; }

    TypedEntity ITypedEntity.Type 
    {
        get
        {
            return this.Type;
        } 
        set 
        {
            this.Type = value as MagazineType; // or throw an exception if value
                                               // is not a MagazineType 
        }
    }
}

用法:

Magazine mag = new Magazine();
mag.Type                 \\ points to `public MagazineType Type { get; set; }`
((ITypedEntity)mag).Type \\ point to `TypedEntity ITypedEntity.Type`

【讨论】:

    【解决方案2】:

    MagazineTypeTypedEntity 并不重要。假设你有另一个ITypedEntity 实现,NewspaperType。 ITypedEntity 接口的合同规定您必须能够做到:

    ITypedEntity magazine = new Magazine();
    magazine.Type = new NewspaperType();
    

    但这与您的代码相矛盾,其中Magazine.Type 不接受ITypedEntity 的其他子类型。 (我相信如果属性只有一个吸气剂,你的代码是有效的。)

    一个解决方案是使用泛型:

    interface ITypedEntity<TType> where TType : TypedEntity
    {
        TType Type { get; set; }
    }
    
    class Magazine : ITypedEntity<MagazineType>
    {
        // ...
    }
    

    【讨论】:

      【解决方案3】:

      您需要将 MagazineType 更改为 TypedEntity

      public class Magazine:INamedEntity,ITypedEntity
      {
      public int Id {get;set;}
      [MaxLength(250)]
      public string Name {get;set;}
      public TypedEntity Type { get; set; }
      }
      

      但是当您创建 Magazine 的对象时,您可以为其分配派生类型

      var magazine = new Magazine { Type = new MagazineType() }
      

      【讨论】:

      • 我知道这行得通,但问题是这是我打算与 EF CodeFirst 一起使用的一些模型,我不确定它是如何工作的,因为我想要一个不同的表对于每个类的 TypedEntity 的具体实现
      猜你喜欢
      • 1970-01-01
      • 2020-01-10
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 2013-09-30
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      相关资源
      最近更新 更多