繁体   English   中英

受保护的构造函数:where new() 约束

[英]Protected constructor for :where new() constraint

我使用装饰模式编写了 class 以避免 inheritance 问题。 我制作了工厂方法来强制组件复制它的实例。 代码将是这样的:

public interface IFoo
{
    int Bar { get; set; }
}

public class Foo : IFoo
{
    public int Bar { get; set; }

    public Foo() { }
}

public abstract class FooDecorator : IFoo
{
    protected IFoo _Foo;
    
    public int Bar
    {
        get
        {
            return _Foo.Bar;
        }
        set
        {
            _Foo.Bar = value;
        }
    }

    public static TOutput Create<TOutput, TInput>(TInput foo)
            where TOutput : FooDecorator, new()
            where TInput : IFoo, new()
    {
        var copy = new TInput
        {
            Bar = foo.Bar
        };
        return new TOutput { _Foo = copy };
        }
    }
}

public class FooDecoratorImpl : FooDecorator
{
    public FooDecoratorImpl() {} // This is necessary only for new() constraint. I'd like to hide it.

    public static FooDecoratorImpl Create<T>(T foo) where T : IFoo, new()
    {
        return Create<FooDecoratorImpl, T>(foo);
    }
}

Foo foo = new Foo() { Bar = 1 };

FooDecoratorImpl decorator = FooDecoratorImpl.Create(foo);
Console.WriteLine(decorator.Bar) // show "1"

FooDecoratorImpl unintended = new FooDecoratorImpl(); // I don't like to do this!

由于默认构造函数在FooDecorator.Create(foo)方法上是只读的,我希望它的访问修饰符设置为protected (我知道这不起作用,因为FooDecorator不是FooDecoratorImpl的派生类型,而是另一种方式轮。)以防止意外实例化。 但是构造函数需要是公开的。 如何限制仅在FooDecorator.Create(foo)上加载构造函数?

使用带有常规构造函数的泛型类:

public abstract class FooDecorator<TSource> : IFoo
    where TSource : IFoo, new()
{
    protected IFoo _Foo;
    
    public int Bar
    {
        get
        {
            return _Foo.Bar;
        }
        set
        {
            _Foo.Bar = value;
        }
    }

    protected FooDecorator(TSource foo)
    {
        // TODO: null check foo
        var copy = new TSource
        {
            Bar = foo.Bar
        };

        _Foo = copy;
    }
}

public class FooDecoratorImpl<TSource> : FooDecorator<TSource>
    where TSource : IFoo, new()
{
    public FooDecoratorImpl(TSource foo)
        : base(foo)
    {
    }
}

Foo foo = new Foo() { Bar = 1 };

var decorator = new FooDecoratorImpl<Foo>(foo);
Console.WriteLine(decorator.Bar) // show "1"

// this won't compile
var unintended = new FooDecoratorImpl<Foo>(); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM