比如有两个类:
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
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
楼上不行啊,
如果这样,
那 类 B 里也没办法创建 A 对象了。就是说只允许 B 能创建 A 对象,不允许其它任何地方能创建 A 对象。
因为 B 会初始化一些 A 的属性。
可以用internal 或者将B嵌套在A内,或者A是抽象,B是A的派生类
嵌套类也不行,因为 A 和 B 是不同层的,分在不同的 dll 里面,不能用嵌套
{
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;
}
}
在不同的dll中,只能通过反射实例化,可以参考7楼的代码,也可以用下面的代码:
A a=Assembly.LoadFile("XXXx.dll").CreateInstance(XXXXXXXXXXXX) as A;
确实,如果真的不能被实例化,将它定义为抽象类就好。
这样如果B是A的派生类,那直接实例化B,或者在B内定义一个A的派生类来实例化。
定义为abstract类型后,反射不了了,你也实例化不了了
在B所在的工程中引用A所在的工程,就能在B代码中直接实例化A实例了。用不着反射。这跟楼主的问题没有关系。
生搬硬套毫无意义,.net框架中也有许多相似的代码,但不是因为不让A能实例化,而是A本身是抽象的,不能实例化。
你需要把A设计为Abstract的类,或者Interface。
就算A设计为Abstract的类,或者Interface,那还需要一个具体的对象来实例化对象,
如果仅仅有Interface,工厂不能直接创建一个 Interface 吧,
还必须有一个实现了该接口的类。
class DefaultA : A{ }
public static A CreateA(){
return new DefaultA();
}
}
工厂模式也只是private后反射的,别纠结这个问题了
只不过感觉不方便而已,或者会影响效率。 System.Diagnostics.StackTrace ss = new System.Diagnostics.StackTrace(true);
System.Reflection.MethodBase mb = ss.GetFrame(1).GetMethod();
string str = mb.DeclaringType.Name;
检测自己的类是否是实现了某个接口?这就跟你的“B中实例化A、工厂”都没有关系。如果只是想提供编程时的可靠性,你可以在A的实例化方法中写Debug.Assert(this.GetType() is IMyInterface);不过这类代码通常是写在测试中,写在最终提交到产品中的代码中是不好的。
public class MyHandler:IHttpHandler
{
void ProcessRequest(HttpContext context){....}
bool IsReusable { .... }
}
----------------
再说了,你已经是工厂了,具体要反射那个类的实例都不确定,只是你写出一个类,就到配置文件中注册一个类,这个本身就独立了,你这是要闹那样啊????
其实这个是有前提的,A中的构造函数是private修饰的。。
这个简单,加 private 很容易。
每辆车都有发动机,那么要写一个发动机的类 class 发动机(){}
我想通过汽车对象来得到一个发动机对象,
而不是直接创建发动机对象,如果我直接创建发动机实例对象,那么就不知道这个发动机是属于哪个汽车的。所以我以前也有些需求。当然也可以用接口,但这样就要写一个接口,写一个实现类。
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());
}
}
http://technet.microsoft.com/zh-cn/magazine/0tke9fxk(VS.90).aspx
{
private function __construct(){
}}
你的工厂方法为什么一定要定义在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难道就不可以反射?
可以这么写:public class A
{
private static A _A;
private A(){}
public static A CreateA()
{
_A = new A();
return _A;
}
}
调用方法: A a = A.CreateA();
{
public A() { ... }
...
}public B
{
public IA CreateA()
{
//通过反射创建A
}
}试试这样