多态性,c#基类调用重写方法中的继承?

多态性,c#基类调用重写方法中的继承?,c#,inheritance,polymorphism,derived-class,base-class,C#,Inheritance,Polymorphism,Derived Class,Base Class,这段代码不起作用,但希望你能得到我在这里试图实现的东西。我有一个Money类,我从中获取,并对它进行了一些扩展,以包括货币转换 每个项目中实际转换率的实现可能不同,因此我决定将检索转换率(GetCurrencyConversionRate)的实际方法移动到派生类中,但是ConvertTo方法包含的代码适用于任何实现,前提是派生类重写了GetCurrencyConversionRate,所以我认为将其保留在父类中是有意义的?所以我要做的是获取SubMoney的一个实例,并能够调用.ConvertT

这段代码不起作用,但希望你能得到我在这里试图实现的东西。我有一个Money类,我从中获取,并对它进行了一些扩展,以包括货币转换

每个项目中实际转换率的实现可能不同,因此我决定将检索转换率(GetCurrencyConversionRate)的实际方法移动到派生类中,但是ConvertTo方法包含的代码适用于任何实现,前提是派生类重写了GetCurrencyConversionRate,所以我认为将其保留在父类中是有意义的?所以我要做的是获取SubMoney的一个实例,并能够调用.ConvertTo()方法,该方法将使用重写的GetCurrencyConversionRate,并返回SubMoney的一个新实例

问题是,我还没有真正理解多态性和继承的一些概念,所以我不太确定我试图做的事情是否有可能以我认为的方式进行,因为目前发生的情况是,我最终遇到了一个异常,它使用了基GetCurrencyConversionRate方法,而不是派生的方法。有些东西告诉我需要将ConvertTo方法向下移动到派生类,但这似乎是在多个实现中复制代码,所以肯定有更好的方法吗

public class Money
{
    public CurrencyConversionRate
    {
        get
        {
            return GetCurrencyConversionRate(_regionInfo.ISOCurrencySymbol);
        }
    }

    public static decimal GetCurrencyConversionRate(string isoCurrencySymbol)
    {
        throw new Exception("Must override this method if you wish to use it.");
    }

    public Money ConvertTo(string cultureName)
    {          
        // convert to base USD first by dividing current amount by it's exchange rate.
        Money someMoney = this;
        decimal conversionRate = this.CurrencyConversionRate;
        decimal convertedUSDAmount = Money.Divide(someMoney, conversionRate).Amount;

        // now convert to new currency
        CultureInfo cultureInfo = new CultureInfo(cultureName);
        RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
        conversionRate = GetCurrencyConversionRate(regionInfo.ISOCurrencySymbol);
        decimal convertedAmount = convertedUSDAmount * conversionRate;
        Money convertedMoney = new Money(convertedAmount, cultureName);
        return convertedMoney;
    }
}

public class SubMoney
{
    public SubMoney(decimal amount, string cultureName) : base(amount, cultureName) {}

    public static new decimal GetCurrencyConversionRate(string isoCurrencySymbol)
    {
        // This would get the conversion rate from some web or database source
        decimal result = new Decimal(2);
        return result;
    }
}

您根本没有使用继承/重写,而是隐藏了该方法

public abstract class Money
{
    public CurrencyConversionRate
    {
        get
        {
            return GetCurrencyConversionRate(_regionInfo.ISOCurrencySymbol);
        }
    }

    public abstract decimal GetCurrencyConversionRate(string isoCurrencySymbol);

    public Money ConvertTo(string cultureName)
    {          
        // convert to base USD first by dividing current amount by it's exchange rate.
        Money someMoney = this;
        decimal conversionRate = this.CurrencyConversionRate;
        decimal convertedUSDAmount = Money.Divide(someMoney, conversionRate).Amount;

        // now convert to new currency
        CultureInfo cultureInfo = new CultureInfo(cultureName);
        RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
        conversionRate = GetCurrencyConversionRate(regionInfo.ISOCurrencySymbol);
        decimal convertedAmount = convertedUSDAmount * conversionRate;
        Money convertedMoney = new Money(convertedAmount, cultureName);
        return convertedMoney;
    }
}

public class SubMoney : Money
{
    public SubMoney(decimal amount, string cultureName) : base(amount, cultureName) {}

    public override decimal GetCurrencyConversionRate(string isoCurrencySymbol)
    {
        // This would get the conversion rate from some web or database source
        decimal result = new Decimal(2);
        return result;
    }
}

如果将方法声明为抽象,则继承类必须重写此方法,从而强制执行自定义代码。当然,您的子Money类必须继承Money才能执行此操作。

您根本没有使用继承/重写,而是隐藏了该方法

public abstract class Money
{
    public CurrencyConversionRate
    {
        get
        {
            return GetCurrencyConversionRate(_regionInfo.ISOCurrencySymbol);
        }
    }

    public abstract decimal GetCurrencyConversionRate(string isoCurrencySymbol);

    public Money ConvertTo(string cultureName)
    {          
        // convert to base USD first by dividing current amount by it's exchange rate.
        Money someMoney = this;
        decimal conversionRate = this.CurrencyConversionRate;
        decimal convertedUSDAmount = Money.Divide(someMoney, conversionRate).Amount;

        // now convert to new currency
        CultureInfo cultureInfo = new CultureInfo(cultureName);
        RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
        conversionRate = GetCurrencyConversionRate(regionInfo.ISOCurrencySymbol);
        decimal convertedAmount = convertedUSDAmount * conversionRate;
        Money convertedMoney = new Money(convertedAmount, cultureName);
        return convertedMoney;
    }
}

public class SubMoney : Money
{
    public SubMoney(decimal amount, string cultureName) : base(amount, cultureName) {}

    public override decimal GetCurrencyConversionRate(string isoCurrencySymbol)
    {
        // This would get the conversion rate from some web or database source
        decimal result = new Decimal(2);
        return result;
    }
}

如果将方法声明为抽象,则继承类必须重写此方法,从而强制执行自定义代码。当然,您的子Money类必须继承Money才能执行此操作。

静态方法只能通过指定声明它的确切类来使用。在这方面没有办法涉及继承

Money
类抽象化,以便必须对其进行派生才能使用。使GetCurrencyConversionRate方法抽象(这也会自动使其虚拟)。使
SubMoney
类继承
Money
并重写
GetCurrencyConversionRate
方法:

public abstract class Money {

  public abstract decimal GetCurrencyConversionRate(string isoCurrencySymbol);

  ...

}

public class SubMoney : Money {

  public override decimal GetCurrencyConversionRate(string isoCurrencySymbol) {
    ...
  }

}

由于该方法是在
Money
类中声明的,因此它知道并可以使用它。创建实例的实际类是派生类,如
SubMoney
,因此始终存在该方法的实现。

静态方法只能通过指定声明它的确切类来使用。在这方面没有办法涉及继承

public abstract class Money
{
    public CurrencyConversionRate
    {
        get
        {
            return GetCurrencyConversionRate(_regionInfo.ISOCurrencySymbol);
        }
    }

    public abstract decimal GetCurrencyConversionRate(string isoCurrencySymbol);

    public Money ConvertTo(string cultureName)
    {          
        // convert to base USD first by dividing current amount by it's exchange rate.
        Money someMoney = this;
        decimal conversionRate = this.CurrencyConversionRate;
        decimal convertedUSDAmount = Money.Divide(someMoney, conversionRate).Amount;

        // now convert to new currency
        CultureInfo cultureInfo = new CultureInfo(cultureName);
        RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
        conversionRate = GetCurrencyConversionRate(regionInfo.ISOCurrencySymbol);
        decimal convertedAmount = convertedUSDAmount * conversionRate;
        Money convertedMoney = new Money(convertedAmount, cultureName);
        return convertedMoney;
    }
}

public class SubMoney : Money
{
    public SubMoney(decimal amount, string cultureName) : base(amount, cultureName) {}

    public override decimal GetCurrencyConversionRate(string isoCurrencySymbol)
    {
        // This would get the conversion rate from some web or database source
        decimal result = new Decimal(2);
        return result;
    }
}
Money
类抽象化,以便必须对其进行派生才能使用。使GetCurrencyConversionRate方法抽象(这也会自动使其虚拟)。使
SubMoney
类继承
Money
并重写
GetCurrencyConversionRate
方法:

public abstract class Money {

  public abstract decimal GetCurrencyConversionRate(string isoCurrencySymbol);

  ...

}

public class SubMoney : Money {

  public override decimal GetCurrencyConversionRate(string isoCurrencySymbol) {
    ...
  }

}

由于该方法是在
Money
类中声明的,因此它知道并可以使用它。创建实例的实际类是派生类,如
SubMoney
,因此始终存在该方法的实现。

GetCurrencyConversionRate
是静态的。无法重写。

GetCurrencyConversionRate
是静态的。无法重写。

另一个选项是使用,通过该选项,您可以抽象算法进行转换,该算法作为自己的类实现。然后,您可以在运行时关闭转换器的实现。这允许您通过在运行时使用某种形式的

public abstract class Money
{
    public CurrencyConversionRate
    {
        get
        {
            return GetCurrencyConversionRate(_regionInfo.ISOCurrencySymbol);
        }
    }

    public abstract decimal GetCurrencyConversionRate(string isoCurrencySymbol);

    public Money ConvertTo(string cultureName)
    {          
        // convert to base USD first by dividing current amount by it's exchange rate.
        Money someMoney = this;
        decimal conversionRate = this.CurrencyConversionRate;
        decimal convertedUSDAmount = Money.Divide(someMoney, conversionRate).Amount;

        // now convert to new currency
        CultureInfo cultureInfo = new CultureInfo(cultureName);
        RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
        conversionRate = GetCurrencyConversionRate(regionInfo.ISOCurrencySymbol);
        decimal convertedAmount = convertedUSDAmount * conversionRate;
        Money convertedMoney = new Money(convertedAmount, cultureName);
        return convertedMoney;
    }
}

public class SubMoney : Money
{
    public SubMoney(decimal amount, string cultureName) : base(amount, cultureName) {}

    public override decimal GetCurrencyConversionRate(string isoCurrencySymbol)
    {
        // This would get the conversion rate from some web or database source
        decimal result = new Decimal(2);
        return result;
    }
}
在设计了一个复杂的系统之后,我明确地认识到了组合优于继承的好处。坦率地说,只有当您的目标是通过多态性增加代码重用时,继承才真正有用。一旦进入继承链深度超过四到五级的复杂类型层次结构,就会与横切关注点发生冲突(这会导致大量复制兄弟类型之间无法共享的非常相似的代码)。组合允许更简单的设计、易于配置(考虑使用xaml在WPF中设计复杂表单)、测试等


无论如何,只是给你一些东西让你从头开始。

另一个选择是使用,通过它,你可以抽象出转换算法,它被实现为自己的类。然后,您可以在运行时关闭转换器的实现。这允许您通过在运行时使用某种形式的

在设计了一个复杂的系统之后,我明确地认识到了组合优于继承的好处。坦率地说,只有当您的目标是通过多态性增加代码重用时,继承才真正有用。一旦进入继承链深度超过四到五级的复杂类型层次结构,就会与横切关注点发生冲突(这会导致大量复制兄弟类型之间无法共享的非常相似的代码)。组合允许更简单的设计、易于配置(考虑使用xaml在WPF中设计复杂表单)、测试等


无论如何,只是给你一些东西让你从头开始。

静态方法根本不能被重写。静态方法根本不能被重写。