只将构造函数暴露给基类,可能吗?

时间:2013-04-18 21:30:59

标签: c# generics inheritance visibility access-modifiers

public class Base<S>
{
    public static Derived<S, T> Create<T>()
    {
        return new Derived<S, T>(); //if not public, I wont get it here.
    }
}

public class Derived<S, T> : Base<S>
{
    public Derived() //the problem, dont want it public
    {

    }
}

这是我得到的基本结构。

要求:

1)我不希望构造Derived<,>的实例完全调用Derived<,>类,无论是通过构造函数还是静态方法。我希望它只能通过Base<>创建。所以这就是:

public class Derived<S, T> : Base<S>
{
    Derived()
    {

    }

    public static Derived<S, T> Create()
    {
        return new Derived<S, T>();
    }
}

2)Derived<,>类本身必须是公共的(这意味着我不能在Derived<,>内私有嵌套Base<>)。只有这样,我才能从Derived<,>中的静态Create方法返回Base<>

有可能吗?

4 个答案:

答案 0 :(得分:3)

您可以在

中创建派生类的构造函数internal
public class Base<S>
{
    public static Derived<S, T> Create<T>()  // visible externally
    {
        return new Derived<S, T>(); 
    }
}

public class Derived<S, T> : Base<S>
{
    internal Derived() // not visible outside the current assembly
    {

    }
}

答案 1 :(得分:1)

反射!

void Main()
{
    Derived dr = Base.GetDerived<Derived>();
}

public class Base
{
    public int ID { get; set; }
    public Base()
    {

    }

    public static T GetDerived<T>() where T : Base
    {
        T toReturn = (T)typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null).Invoke(null);
        return toReturn;
    }

}

public class Derived : Base
{
    private Derived()
    {

    }
}

答案 2 :(得分:0)

我以这种方式达到了我的要求:

public abstract class Base<S>
{
    public static Derived<S, T> Create<T>() 
    {
        return new ReallyDerived<S, T>(); 
    }



    class ReallyDerived<T> : Derived<S, T>
    {
        public ReallyDerived()
        {

        }
    }
}

public abstract class Derived<S, T> : Base<S>
{

}

现在这可行..

答案 3 :(得分:0)

我会声明一个公共接口,并在Base

中将实现设为私有
public class Base<S>
{
    public static IFoo<S, T> Create<T>()
    {
        return new Derived<T>(); //if not public, I wont get it here.
    }

    // Only generic in T, as we can use S from the containing class
    private class Derived<T> : Base<S>, IFoo<S, T>
    {
        public Derived()
        {
            ...
        }
    }
}

public interface IFoo<S, T>
{
    // Whatever members you want
}