C# 如何修改此代码以允许抽象类或接口在相同的自动生成类上工作?

C# 如何修改此代码以允许抽象类或接口在相同的自动生成类上工作?,c#,oop,inheritance,interface,abstract-class,C#,Oop,Inheritance,Interface,Abstract Class,解释 我使用xsd.exe工具根据xsd(定义XML文件的模式)生成一个类API,从中与XML文件交互 这个工具工作得很好,但问题是我有一些基本相同的模式,但有一些小的调整,所以我想创建接口或抽象类,允许我在其他地方重用代码 在我下面的示例中,为了在这里共享,我简化了生成的代码,但原则仍然成立 不起作用的代码示例 Program.cs public static void Main() { BaseColor baseColor = new Color1 { ColorDescripti

解释

我使用
xsd.exe
工具根据xsd(定义XML文件的模式)生成一个类API,从中与XML文件交互

这个工具工作得很好,但问题是我有一些基本相同的模式,但有一些小的调整,所以我想创建接口或抽象类,允许我在其他地方重用代码

在我下面的示例中,为了在这里共享,我简化了生成的代码,但原则仍然成立

不起作用的代码示例

Program.cs

public static void Main()
{
    BaseColor baseColor = new Color1 { ColorDescription = "Red" };
    BaseShape baseShape = new Shape1 { Content = baseColor };
}
模型.cs

//Auto generated models - I have no control over these but they are partial classes

//First set of autogenerated models, normally in its own file
public partial class Shape1
{
    public Color1 Content { get; set; }
}

public partial class Color1
{

    public string ColorDescription { get; set; }
}

//Second set of autogenerated models, normally in its own file
public partial class Shape2
{
    public Color2 Content { get; set; }
}

public partial class Color2
{

    public string ColorDescription { get; set; }
}

//Attemping to abstract these classes so I can generically use them regardless of underlying type
public abstract class BaseShape
{
    public abstract BaseColor Content { get; set; }
}

public abstract class BaseColor
{
    public abstract string ColorDescription { get; set; }
}

//Attempting to extend the autogenerated classes with the abstract classes
public partial class Shape1 : BaseShape { }

public partial class Color1 : BaseColor { }

public partial class Shape2 : BaseShape { }

public partial class Color2 : BaseColor { }
错误

对于两种形状、两种颜色和两种获取/设置方法,此错误总共重复8次

'Shape1' does not implement inherited abstract member 'BaseShape.Content.set'   XmlSerializeChild
Main
方法

Cannot implicitly convert type 'XmlSerializeChild.Models.BaseColor' to 'XmlSerializeChild.Models.Color1'. An explicit conversion exists (are you missing a cast?)

您的位置非常接近,但正如将军在他的评论中所写,您不能在重写属性时更改属性的类型

您可以做的是引入一个新属性(我选择使用接口,但它也适用于抽象类),该属性将在代码中使用,在每个分部类中具有显式强制转换:

首先,我创建了接口:

public interface IColor { string ColorDescription { get; set; } }

public interface IShape { IColor BaseContent { get; set; } }
然后,将
IColor
实现添加到
Color1
Color2
类中:

public partial class Color1 : IColor {}
public partial class Color2 : IColor {}
public partial class Shape1 : IShape 
{
    public IColor BaseContent
    {
        get { return Content; }
        set { Content = (Color1) value; }
    }
}

public partial class Shape2 : IShape 
{
    public IColor BaseContent
    {
        get { return Content; }
        set { Content = (Color2) value; }
    }
}
(这很简单,因为两种颜色的颜色描述类型相同)

接下来,我将
IShape
实现添加到
Shape1
Shape2
类中:

public partial class Color1 : IColor {}
public partial class Color2 : IColor {}
public partial class Shape1 : IShape 
{
    public IColor BaseContent
    {
        get { return Content; }
        set { Content = (Color1) value; }
    }
}

public partial class Shape2 : IShape 
{
    public IColor BaseContent
    {
        get { return Content; }
        set { Content = (Color2) value; }
    }
}
现在,在
Main
方法中,您可以执行以下操作:

var baseColor = new Color1() { ColorDescription = "Red" };
var baseShape = new Shape1() { BaseContent = baseColor };
另一个选项是隐式实现
IShape
接口,而不是引入新属性,但这将更加麻烦,并且不允许您使用
new Shape1(){Content=baseColor}
语法。尽管如此,我们还是来回顾一下这个选项:

因此,我们在
IShape
界面中重命名
BaseContent
属性:

interface IShape { IColor Content { get; set; } }
我们是这样实施的:

public partial class Shape1 : IShape 
{
    IColor IShape.Content 
    {
        get { return ((Shape1)this).Content; }
        set { ((Shape1)this).Content = (Color1) value; }
    }
}

public partial class Shape2 : IShape 
{
    IColor IShape.Content 
    {
        get { return ((Shape2)this).Content; }
        set { ((Shape2)this).Content = (Color2) value; }
    }
}
var baseColor = new Color1() { ColorDescription = "Red" };
// Note: Do not use var here - you need the reference to be of type `IShape`!
IShape baseShape = new Shape1();
baseShape.Content = baseColor;
然后,我们创造了这样的崇敬:

public partial class Shape1 : IShape 
{
    IColor IShape.Content 
    {
        get { return ((Shape1)this).Content; }
        set { ((Shape1)this).Content = (Color1) value; }
    }
}

public partial class Shape2 : IShape 
{
    IColor IShape.Content 
    {
        get { return ((Shape2)this).Content; }
        set { ((Shape2)this).Content = (Color2) value; }
    }
}
var baseColor = new Color1() { ColorDescription = "Red" };
// Note: Do not use var here - you need the reference to be of type `IShape`!
IShape baseShape = new Shape1();
baseShape.Content = baseColor;

您的位置非常接近,但正如将军在他的评论中所写,您不能在重写属性时更改属性的类型

您可以做的是引入一个新属性(我选择使用接口,但它也适用于抽象类),该属性将在代码中使用,在每个分部类中具有显式强制转换:

首先,我创建了接口:

public interface IColor { string ColorDescription { get; set; } }

public interface IShape { IColor BaseContent { get; set; } }
然后,将
IColor
实现添加到
Color1
Color2
类中:

public partial class Color1 : IColor {}
public partial class Color2 : IColor {}
public partial class Shape1 : IShape 
{
    public IColor BaseContent
    {
        get { return Content; }
        set { Content = (Color1) value; }
    }
}

public partial class Shape2 : IShape 
{
    public IColor BaseContent
    {
        get { return Content; }
        set { Content = (Color2) value; }
    }
}
(这很简单,因为两种颜色的颜色描述类型相同)

接下来,我将
IShape
实现添加到
Shape1
Shape2
类中:

public partial class Color1 : IColor {}
public partial class Color2 : IColor {}
public partial class Shape1 : IShape 
{
    public IColor BaseContent
    {
        get { return Content; }
        set { Content = (Color1) value; }
    }
}

public partial class Shape2 : IShape 
{
    public IColor BaseContent
    {
        get { return Content; }
        set { Content = (Color2) value; }
    }
}
现在,在
Main
方法中,您可以执行以下操作:

var baseColor = new Color1() { ColorDescription = "Red" };
var baseShape = new Shape1() { BaseContent = baseColor };
另一个选项是隐式实现
IShape
接口,而不是引入新属性,但这将更加麻烦,并且不允许您使用
new Shape1(){Content=baseColor}
语法。尽管如此,我们还是来回顾一下这个选项:

因此,我们在
IShape
界面中重命名
BaseContent
属性:

interface IShape { IColor Content { get; set; } }
我们是这样实施的:

public partial class Shape1 : IShape 
{
    IColor IShape.Content 
    {
        get { return ((Shape1)this).Content; }
        set { ((Shape1)this).Content = (Color1) value; }
    }
}

public partial class Shape2 : IShape 
{
    IColor IShape.Content 
    {
        get { return ((Shape2)this).Content; }
        set { ((Shape2)this).Content = (Color2) value; }
    }
}
var baseColor = new Color1() { ColorDescription = "Red" };
// Note: Do not use var here - you need the reference to be of type `IShape`!
IShape baseShape = new Shape1();
baseShape.Content = baseColor;
然后,我们创造了这样的崇敬:

public partial class Shape1 : IShape 
{
    IColor IShape.Content 
    {
        get { return ((Shape1)this).Content; }
        set { ((Shape1)this).Content = (Color1) value; }
    }
}

public partial class Shape2 : IShape 
{
    IColor IShape.Content 
    {
        get { return ((Shape2)this).Content; }
        set { ((Shape2)this).Content = (Color2) value; }
    }
}
var baseColor = new Color1() { ColorDescription = "Red" };
// Note: Do not use var here - you need the reference to be of type `IShape`!
IShape baseShape = new Shape1();
baseShape.Content = baseColor;

覆盖时无法更改类型。您还需要
override
关键字,您需要重新考虑这一点。是否有其他方法的想法?我唯一的限制是不能修改自动生成的文件。重写时不能更改类型。您还需要
override
关键字,您必须重新考虑这一点。是否有其他方法的想法?我唯一的限制是我不能修改自动生成的文件。argggg你打败了我,向上投票,也少捣乱了arggg你打败了我,向上投票,也少捣乱了