2011-05-03 33 views
4

是否有可能在运行时为类选择命名空间。我们在不同的命名空间中有两个自动生成的对象。这里有一个例子:c#中运行时从不同的命名空间中选择对象?

Namespace1 
    ClassA 
    ClassB 

Namaspace2 
    ClassA 
    ClassB 

以前,代码是简单的像下面

using Namespace1 
... 
    ClassA.AMethod() 

然而,我们需要使用条件变量来选择在运行时的命名空间。有没有一种方法来定义一个GetNamespace()方法并像下面那样使用它,或者有其他建议吗?

GetNamespace().ClassA.AMethod() 

干杯, 布拉克

+1

你说这些类是自动生成的。是否有可能修改这一代,以便这些类中的每一个都从一个公共基类继承或实现一个通用接口(例如,这两个ClassAs派生自ClassABase)?如果是这样,您可以使用基类/接口编写代码。剩下的挑战就是对象创建。 – 2011-05-03 07:35:25

回答

1

据我所知,目前还没有办法动态选择的命名空间,但我认为你在完美的情况是使用factory

namespace Common { 

public abstract class AbsA 
{ 
    //... 
} 

public class MyFactory 
{ 
    public MyFactory() 
    { 
     //... 
    } 

    public AbsA getA() 
    { 
     AbsA a; 
     if (condition) 
      a = new Namespace1.A(); 
     else 
      a = new Namespace2.A(); 
     return a; 
    } 
} 

} 

然后你问你的工厂创建对象:

MyFactory factory = new MyFactory(); 
labelMessage.Text = factory.getA().Something; 

这有点复杂的结构,但也使得它更要做到这一点,你的所有A类必须从一个抽象推导相干。

+0

谢谢。在创建工厂之前,作为一个没有经验的c#程序员,我希望可能有一个简单的解决方案,但似乎没有。 – 2011-05-03 11:09:51

1

两个不同的命名空间类型完全不同类型至于CLR关注。基本上你需要考虑与在任何其他任意类型之间进行选择相同的解决方案。使这两个类实现相同的接口,而不是GetNamespace()返回一个名称空间,它将不得不返回该对象本身。

1

既然你可以:

var type = Type.GetType("Namespace1.ClassA"); 
object instance = Activator.CreateInstance(type); 

然后,如果您想调用该实例的方法,你需要或者将它转换为一个通用的接口,或者得到MethodInfo实例调用。如果你控制类的产生,我会建议接口的方法:

public interface IClassA 
{ 
    void AMethod(); 
} 

namespace Namespace1 
{ 
    public class ClassA : IClassA 
    { /* Stuff... */ } 
} 

这样,你只需要:

var type = Type.GetType("Namespace1.ClassA"); 
IClassA instance = (IClassA)Activator.CreateInstance(type); 

instance.AMethod(); 

使用工具如的LINQ到SQL的大多数自动生成的类,实体框架,甚至WCF代理创建为partial,这意味着您可以创建一个额外的文件,例如ClassA.partial.cs更增添了你的类的声明,而无需修改自动生成的类:

partial class ClassA : IClassA { }