防止使用抽象类作为属性类型

时间:2017-12-28 08:35:25

标签: c# class inheritance abstract

是否可以阻止使用抽象类作为属性类型?

我有一个抽象基类,它在具有泛型类型的抽象类中继承,而泛型类又在具有已定义类型的类中继承。有可能"锁定"具有泛型类型的抽象类,因此无法将其用作其他类中的属性?

这是我的情况的近似值。我想阻止创建像doubleFoo2这样的属性的可能性。 Foo<T>应该只能在其他类中继承,并且不能直接用作类型。

由于我验证了PropertyType属性及其基本类型,这导致我犯了一个错误,我花了一段时间才找到。这是对代码的测试:https://dotnetfiddle.net/OMHmGv

public abstract class FooBase
{
    // Various generic properties and methods
}

public abstract class Foo<T> : FooBase 
{
    public Type ValueType { get { return typeof(T); } }
    public abstract T Value { get; set; }
}

public class DoubleFoo : Foo<double> 
{
    public override double Value { get; set; }
}

public class FooHandler
{
    public DoubleFoo doubleFoo1 { get; set; }
    public Foo<double> doubleFoo2 { get; set; }
}

2 个答案:

答案 0 :(得分:4)

这不仅是不可能的,它违背了面向对象编程的三个基本原则之一 - 当然,我正在谈论polymorphism。 放弃多态性是完全放弃面向对象的编程。

关键是类型的引用实际上可以引用从引用类型派生的任何类型的实例。

多态性使得以下代码行完全有效(即使不是很有用):

{event: Array(0), profile: Array(0), account: Array(1), onUserLogin: Array(0), notifications: Array(0), …} 

答案 1 :(得分:0)

编辑:就像@Zohar Peled所说的那样,它违背了多态性的目的,限制基于命名空间或汇编的使用是你唯一的方法。

如果DoubleFoo及其子类是在单独的程序集中创建的,则可以使用

  

内部

修饰符而不是

  

公共

用于FooBase和Foo类,以防止其他程序集访问它们。

如果必须在同一个程序集中使用此DoubleFoo,则可以尝试将基类放在不同的命名空间中以隐藏基本实现类。 一个例子是:

在FooOfT.cs内部

namespace FooTester.DoubleFoo.Foo
{
    public abstract class FooBase
    {
        // Various generic properties and methods
    }

    public abstract class Foo<T> : FooBase 
    {
        public Type ValueType { get { return typeof(T); } }
        public abstract T Value { get; set; }
    }
}

DoubleFoo.cs内部

using FooTester.DoubleFoo.Foo

namespace FooTester.DoubleFoo
{
    public class DoubleFoo : Foo<double> 
    {
        public override double Value { get; set; }
    }
}

在FooHandler.cs里面

using FooTester.DoubleFoo

namespace FooTester
{
    public class FooHandler
    {
        public DoubleFoo doubleFoo1 { get; set; }
        // public Foo<double> doubleFoo2 { get; set; } Cannot access Foo<T> class
    }
}