【问题标题】:C# abstract base class - extending the implementationC# 抽象基类 - 扩展实现
【发布时间】:2012-05-03 08:50:28
【问题描述】:

我有以下情况:

   public class GeoLocation
   {
       public double Longitude { get; set; }
       public double Latitude { get; set; }
       public string LocationName { get; set; }
   }

    public abstract class Base
    {
        public abstract GeoLocation GeoLocation { get; set; }
    }

    public class Concrete : Base
    {
        public override GeoLocation GeoLocation
        {
            get;
            set;
        }
    }

现在,如果我创建一个类 Concrete2,它也继承自 Base,并且我希望 GeoLocation 对象拥有更多属性:

public string Address{ get; set; }

实现这一点的最佳方法是什么?

我可以创建一个名为 GeoLocationEx : GeoLocation 的新类并将 Address 属性放在那里,但是在我的 Concrete2 对象中,我将有 2 个属性:GeoLocationGeoLocationEx,我不喜欢它们......

我还可以将 GeoLocation 类设为局部类,并使用 Address 属性扩展它以用于 Concrete2 类,但我不确定这是否是对局部类的“正确”使用。

最好的方法是什么?

提前感谢您的帮助!

【问题讨论】:

  • 为什么要让后代类使用扩展的GeoLocation 对象?在这种情况下,如果您想通过Base 的接口使用Concrete2 对象,则必须检查它是否是Concrete2 对象,而不是Concrete,然后才传入GeoLocationEx 对象。
  • 为什么不能简单地将“地址”添加到 GeoLocation 对象?
  • 我在看这篇文章时找到了解决方案:abstract class Request where T : Parameters { T Parameters; } 类专业化:请求 { }
  • 从基类继承的某些类在此 GeoLocation 属性中具有与其他不同的属性...

标签: c# abstract extend base


【解决方案1】:

你可能会使用泛型:

        public class GeoLocation
        {
            public double Longitude { get; set; }
            public double Latitude { get; set; }
            public string LocationName { get; set; }
        }

        public class GeoLocationEx : GeoLocation
        {
            public double Address { get; set; }
        }

        public abstract class Base<T>
        {
            public abstract T GeoLocation { get; set; }
        }

        public class Concrete : Base<GeoLocation>
        {
            public override GeoLocation GeoLocation
            {
                get;
                set;
            }
        }

        public class Concrete2 : Base<GeoLocationEx>
        {
            public override GeoLocationEx GeoLocation
            {
                get;
                set;
            }
        }

【讨论】:

  • 这个问题是Concrete和Concrete2不共享同一个基类。
  • 我选择了通用解决方案...谢谢!
【解决方案2】:
public class GeoLocation
{
    public GeoLocation(GeoLocation obj) {/* implement a copy constructor */}
    public GeoLocation() {/* default constructor */}

    public double Longitude { get; set; }
    public double Latitude { get; set; }
    public string LocationName { get; set; }
}

public class GeoLocationEx : GeoLocation
{
    public string Address { get; set; }
}

public abstract class Base
{
    public abstract GeoLocation GeoLocation { get; set; }
}

public class Concrete2 : Base
{
    private GeoLocationEx _geoLocation;
    public override GeoLocation GeoLocation
    {
        get { return _geoLocation; }
        set
        {
            _geoLocation = new GeoLocationEx(value);
        }
    }
}

现在在Concrete2 类中,您可以直接使用私有GeoLocationEx 字段。此外,您可以为Concrete2 特定的东西公开其他公共方法。

关于编写复制构造函数参考MSDN:http://msdn.microsoft.com/en-us/library/ms173116(v=vs.80).aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-26
    • 2013-03-27
    • 2016-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-29
    • 2022-07-08
    相关资源
    最近更新 更多