比如有两个类:
class A{
...
}class B{
   public static A createA();
}
类A不能直接实例化,如  A a = new A();
禁止象上面直接实例化,
而必须通过B的方法来创建A,
如:
   A a = B.createA();就是说:
  A a = new A();  //不允许这样直接实例化
  A a = B.createA();  //只能通过B来创建A

解决方案 »

  1.   

    private  A(){}
      

  2.   


    楼上不行啊,
    如果这样,
    那 类 B 里也没办法创建 A 对象了。就是说只允许 B 能创建 A 对象,不允许其它任何地方能创建 A 对象。
    因为 B 会初始化一些 A 的属性。
      

  3.   

    本帖最后由 net_lover 于 2012-10-03 14:33:02 编辑
      

  4.   


    可以用internal 或者将B嵌套在A内,或者A是抽象,B是A的派生类
      

  5.   


    嵌套类也不行,因为 A 和 B 是不同层的,分在不同的 dll 里面,不能用嵌套
      

  6.   

        class Program
        {
            static void Main(string[] args)
            {
                A a=B.CreateA();
                Console.WriteLine(a.aa);
                Console.Read();
            }
        }
        class A {
            private A()//禁止直接实例化
            { 
            
            }
            public int aa = 2;
        }
        class B
        {
            public static A CreateA()
            {
                //通过反射实例化
                Type t = typeof(A);
                A a = t.Assembly.CreateInstance(t.FullName, false, BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.ExactBinding, null, null, null, null) as A;
                return a;
            }
        }
      

  7.   

    本帖最后由 net_lover 于 2012-10-03 14:39:37 编辑
      

  8.   

    分在不同工程!呵呵。不要管它了。不用禁止。这就好比如说你找了个一开始就被定义为相当自由的女朋友,你想给她戴上贞洁带,那是纠结的。还不如不用管了,看看能测试出什么bug来?!
      

  9.   


    在不同的dll中,只能通过反射实例化,可以参考7楼的代码,也可以用下面的代码:
    A a=Assembly.LoadFile("XXXx.dll").CreateInstance(XXXXXXXXXXXX) as A;
      

  10.   


    确实,如果真的不能被实例化,将它定义为抽象类就好。
    这样如果B是A的派生类,那直接实例化B,或者在B内定义一个A的派生类来实例化。
      

  11.   

    编程以系统集成测试为原则,而不是以所谓的“封闭概念、个人洁癖”为原则。很多时候为了让程序可测,我们需要把private的方法定义修改为public的,仅仅是为了迎合自动化测试系统的需要。此时不用过度纠结于作用域定义,让我们看看测试工程能测试什么bug来?!
      

  12.   

    其实反射也是实例化的一种方法,你如果真的禁止实例化,反射也应该禁止才行,实际上你禁止不了。
    定义为abstract类型后,反射不了了,你也实例化不了了
      

  13.   


    在B所在的工程中引用A所在的工程,就能在B代码中直接实例化A实例了。用不着反射。这跟楼主的问题没有关系。
      

  14.   


    生搬硬套毫无意义,.net框架中也有许多相似的代码,但不是因为不让A能实例化,而是A本身是抽象的,不能实例化。
      

  15.   


    你需要把A设计为Abstract的类,或者Interface。
      

  16.   


    就算A设计为Abstract的类,或者Interface,那还需要一个具体的对象来实例化对象,
    如果仅仅有Interface,工厂不能直接创建一个 Interface 吧,
    还必须有一个实现了该接口的类。
      

  17.   

    自己看11楼public abstract class A {  }public class B{
       class DefaultA : A{    }
       
       public static A CreateA(){
          return new DefaultA();
       }
    }
      

  18.   

    B中CreateA返回的对象类型,可以是B所在的工程的作用域私有的(Internal),别的工程轻易访问不了。(当然其实反射等方法照样可以访问到)。工厂是要定义出抽象的返回值类型,只是工厂的概念。
      

  19.   


    工厂模式也只是private后反射的,别纠结这个问题了
      

  20.   

    我只要能检测到创建自己的是哪个类,就可以绝对禁止实例化了。
    只不过感觉不方便而已,或者会影响效率。                System.Diagnostics.StackTrace ss = new System.Diagnostics.StackTrace(true);
                    System.Reflection.MethodBase mb = ss.GetFrame(1).GetMethod();
                   
                    string str = mb.DeclaringType.Name;
      

  21.   


    检测自己的类是否是实现了某个接口?这就跟你的“B中实例化A、工厂”都没有关系。如果只是想提供编程时的可靠性,你可以在A的实例化方法中写Debug.Assert(this.GetType() is IMyInterface);不过这类代码通常是写在测试中,写在最终提交到产品中的代码中是不好的。
      

  22.   

    OMG,楼主还不是一般的钻牛角尖,比如IHttpHandler这个接口,你写一个继承这个接口的类时候,我们也不会禁止别人实例化的:
    public class MyHandler:IHttpHandler
    {
    void ProcessRequest(HttpContext context){....}
    bool IsReusable { .... }
    }
    ----------------
    再说了,你已经是工厂了,具体要反射那个类的实例都不确定,只是你写出一个类,就到配置文件中注册一个类,这个本身就独立了,你这是要闹那样啊????
      

  23.   

    嗯,修改一下,是Debug.Assert(typeof(IMyInterface).IsAssignableFrom(this.GetType()));或者Debug.Assert(this is IMyInterface);这跟你原先问题没有关系了。这根本不能禁止别人直接实例化A。看来你已经转到别的思路上去了,与这个问题无关了!
      

  24.   

    不是自己实例化某个接口,而是创建自己的类是否实现了某个接口,比如 B 创建 A,要求 B要实现某个接口。
      

  25.   


    其实这个是有前提的,A中的构造函数是private修饰的。。
      

  26.   


    这个简单,加 private 很容易。
      

  27.   

    http://msdn.microsoft.com/zh-cn/library/c5kehkcz.aspx
      

  28.   

    这也是我想问的比如一辆汽车,class 汽车(){}
    每辆车都有发动机,那么要写一个发动机的类 class 发动机(){}
    我想通过汽车对象来得到一个发动机对象,
    而不是直接创建发动机对象,如果我直接创建发动机实例对象,那么就不知道这个发动机是属于哪个汽车的。所以我以前也有些需求。当然也可以用接口,但这样就要写一个接口,写一个实现类。
      

  29.   

    A.javapublic class A {
        private A() {
        }
    }
    B.javapublic final class B {
        public static A createA() throws SecurityException, NoSuchMethodException,
                IllegalArgumentException, InstantiationException,
                IllegalAccessException, InvocationTargetException {
            Constructor<A> constructor = null;
            try {
                Class<A> clazz = A.class;
                constructor = clazz.getDeclaredConstructor();
                constructor.setAccessible(true);
                return constructor.newInstance();
            } finally {
                if (constructor != null) {
                    constructor.setAccessible(false);
                }
            }
        }    public static void main(String[] args) throws InstantiationException,
                IllegalAccessException, SecurityException, NoSuchMethodException,
                IllegalArgumentException, InvocationTargetException {
            System.out.println(B.createA().hashCode());
        }
    }
      

  30.   

    A如果设为私有类的话,就只能在加一个接口了,B类创建A但返回A的接口就行了。
      

  31.   

    不知道这个 能不能帮助楼主解决问题
    http://technet.microsoft.com/zh-cn/magazine/0tke9fxk(VS.90).aspx
      

  32.   

    class Test
    {
        private function __construct(){
             
        }}
      

  33.   

    不觉得这个问题很2吗?
    你的工厂方法为什么一定要定义在class B 里面呢? 为什么不直接定义在class A里面呢? 有谁说了工程的类型和被创建的类型必须是不同的类型呢? 没事多看看反编译的.net运行库。如果要用class B来构造A对象,那么只能是B 和 A在一个assembly里面,A的构造是internal的。如果你还非要把class B定义在另外一个assembly里面,而且还只能有B来构造A对象,那么抛开C#的语法来说,B所在的project肯定需要引用A的project, 而A也必然需要通过某种语法指定说自己只能被B创建,那么意味着A的project必须要引用B的project。A B project 互相引用,意味着什么?意味着他么之间互相耦合依赖,那么本来就应该合并为一个project,那么解决方案还是internal那种。.net中工厂模式实现有若干种典型方式
    1. class A定义构造为私有,由class自己提供静态方法创建实例。
    2. class A为抽象,若干子类型B,C,D,E..都设置构造为internal,由A类或者第三方类型提供静态方法构造实例。
    3. 相互关联的对象之间进行创建,比如IDBConnection创建IDBCommand,这种实际上是抽象类工厂模式,两个具体类型应该在同一个assembly,而且有可能并不禁止对象直接实例化。至于反射之类的方法就没有意义了,对吗? B可以反射,C难道就不可以反射?
      

  34.   


    可以这么写:public class A
    {
     private static A _A;
     private A(){}
     public static A CreateA()
     {
       _A = new A();
       return _A;
     }
    }
    调用方法: A a = A.CreateA();
      

  35.   

    public interface IA { ... }private A : IA 
    {
       public A() { ... }
       ...
    }public B 
    {
       public IA CreateA()
       {
          //通过反射创建A
       }
    }试试这样
      

  36.   

    是的,有些时候(不是说要放纵)不能够纠结于private和public,否则很肯能是自讨苦吃,而且不一定能达到目的。