简体   繁体   English

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

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

I wrote a class using Decoration Pattern to avoid inheritance issues.我使用装饰模式编写了 class 以避免 inheritance 问题。 And I made Factory Method to enforce component to copy its instance.我制作了工厂方法来强制组件复制它的实例。 The code would be like this:代码将是这样的:

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!

Since the default constructor is read only on the FooDecorator.Create(foo) method, I'd like its access modifier set to protected (I knew this doesn't work because FooDecorator isn't FooDecoratorImpl 's derived type, but the other way round.) to prevent unintended instantiation.由于默认构造函数在FooDecorator.Create(foo)方法上是只读的,我希望它的访问修饰符设置为protected (我知道这不起作用,因为FooDecorator不是FooDecoratorImpl的派生类型,而是另一种方式轮。)以防止意外实例化。 But the constructor needs to be public.但是构造函数需要是公开的。 How can I restrict the constructor to be loaded on FooDecorator.Create(foo) only?如何限制仅在FooDecorator.Create(foo)上加载构造函数?

Use generic classes with regular constructors:使用带有常规构造函数的泛型类:

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