在 C# 中访问其成员函数时如何防止调用一个 class 的构造函数?
How to prevent calling constructor of one class while having access to its member functions in C#?
我有一个classA
和一个classAStore
。我的要求是防止所有其他方法初始化 class A
的实例,它们应该从 AStore
获取实例。另外,我还需要从实例中访问A
的成员函数。
工厂模式不适用于此问题,因为 A
的构造函数仍然是 public。理想情况下,在访问其成员函数时调用 class A
的构造函数时应该抛出编译错误。
我可以获得此问题的 C# 解决方案吗?
为了限制其他人创建 class A 的实例,您可以使用私有构造函数和静态工厂方法来获取 class 的实例。
public class A
{
private A(){}
public static A GetInstance()
{
return new A();
}
public void MemberFunctionOfA()
{
// blah blah...
}
}
要强制仅通过 Astore 创建 A 的实例,您可以使用受保护的修饰符并从 A 派生 AStore。这样,只有 AStore 才能访问其受保护的成员,如 'constructor' 或 'factory method':
public class Astore : A
{
public A GetInstanceOfA()
{
return base.GetInstance();
}
}
public class A
{
protected A() { }
protected A GetInstance()
{
return new A();
}
public void MemberFunctionOfA()
{
// blah blah...
}
}
//Usage
public class ConsumerClass
{
public void Test()
{
var a = new A(); // Compile error
a = new Astore().GetInstanceOfA();
a.MemberFunctionOfA();
}
}
但是另一个 class 说 'UnWantedStore' 仍然有可能派生自 A 并提供 A 的实例。
你也可以用反射来做到这一点:
public class ClassA
{
// The constructor(s) have to be private
private ClassA() { }
// Whatever other code you want
}
public class ClassB
{
public static ClassA GetClassAInstance()
{
// Use reflection to get the private default constructor
ConstructorInfo constructor = typeof(ClassA).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
ClassA instance = constructor.Invoke(new object[] { }) as ClassA;
return instance;
}
}
您可以找到有关 GetConstructor 方法的更多信息 here。
另一种方法是将 AStore
和 A
classes 移动到专用项目,并将 A
class 的构造函数内部化。
// Project A
namespace ProjectA
{
public class A
{
public int PropertyOne { get; set; }
public string PropertyTwo { get; set; }
internal A() {}
}
public class AStore
{
public A CreateA()
{
//internal constructor can be used
return A();
}
}
}
// Project ConsumerOfA
namespace ConsumerOfA
{
public static void UseA()
{
var store = new AStore();
var instanceOfA = store.CreateA();
// have access to the A's public members
}
}
通过这种方法,您将获得您想要实现的完美封装。
摘要 class 来拯救!
的确,还有另一种可能的方法!我从未使用过它,但它可能适用于您的场景。请参阅以下代码示例:
public abstract class A
{
public string Text { get; set; }
public string SayHello() => "hello world!";
}
public class AStore
{
private class AInternal : A {}
public void DoStuff()
{
A a = new AInternal();
a.Text = "whatever";
string helloText = a.SayHello();
}
}
让我们解释一下方法:
- Class
A
是抽象的,因此无法实例化。
- Class
AStore
实现了一个名为 AInternal
的 private
嵌套 class,它继承了 A
让 AStore
成员能够实例化A
。由于 AInternal
是私有的,除 AStore
之外没有其他 class 可以实例化 AInternal
!
- Class
AStore
可以访问 public A
成员,因为 AInternal
继承了 A
!
我有一个classA
和一个classAStore
。我的要求是防止所有其他方法初始化 class A
的实例,它们应该从 AStore
获取实例。另外,我还需要从实例中访问A
的成员函数。
工厂模式不适用于此问题,因为 A
的构造函数仍然是 public。理想情况下,在访问其成员函数时调用 class A
的构造函数时应该抛出编译错误。
我可以获得此问题的 C# 解决方案吗?
为了限制其他人创建 class A 的实例,您可以使用私有构造函数和静态工厂方法来获取 class 的实例。
public class A
{
private A(){}
public static A GetInstance()
{
return new A();
}
public void MemberFunctionOfA()
{
// blah blah...
}
}
要强制仅通过 Astore 创建 A 的实例,您可以使用受保护的修饰符并从 A 派生 AStore。这样,只有 AStore 才能访问其受保护的成员,如 'constructor' 或 'factory method':
public class Astore : A
{
public A GetInstanceOfA()
{
return base.GetInstance();
}
}
public class A
{
protected A() { }
protected A GetInstance()
{
return new A();
}
public void MemberFunctionOfA()
{
// blah blah...
}
}
//Usage
public class ConsumerClass
{
public void Test()
{
var a = new A(); // Compile error
a = new Astore().GetInstanceOfA();
a.MemberFunctionOfA();
}
}
但是另一个 class 说 'UnWantedStore' 仍然有可能派生自 A 并提供 A 的实例。
你也可以用反射来做到这一点:
public class ClassA
{
// The constructor(s) have to be private
private ClassA() { }
// Whatever other code you want
}
public class ClassB
{
public static ClassA GetClassAInstance()
{
// Use reflection to get the private default constructor
ConstructorInfo constructor = typeof(ClassA).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
ClassA instance = constructor.Invoke(new object[] { }) as ClassA;
return instance;
}
}
您可以找到有关 GetConstructor 方法的更多信息 here。
另一种方法是将 AStore
和 A
classes 移动到专用项目,并将 A
class 的构造函数内部化。
// Project A
namespace ProjectA
{
public class A
{
public int PropertyOne { get; set; }
public string PropertyTwo { get; set; }
internal A() {}
}
public class AStore
{
public A CreateA()
{
//internal constructor can be used
return A();
}
}
}
// Project ConsumerOfA
namespace ConsumerOfA
{
public static void UseA()
{
var store = new AStore();
var instanceOfA = store.CreateA();
// have access to the A's public members
}
}
通过这种方法,您将获得您想要实现的完美封装。
摘要 class 来拯救!
的确,还有另一种可能的方法!我从未使用过它,但它可能适用于您的场景。请参阅以下代码示例:
public abstract class A
{
public string Text { get; set; }
public string SayHello() => "hello world!";
}
public class AStore
{
private class AInternal : A {}
public void DoStuff()
{
A a = new AInternal();
a.Text = "whatever";
string helloText = a.SayHello();
}
}
让我们解释一下方法:
- Class
A
是抽象的,因此无法实例化。 - Class
AStore
实现了一个名为AInternal
的private
嵌套 class,它继承了A
让AStore
成员能够实例化A
。由于AInternal
是私有的,除AStore
之外没有其他 class 可以实例化AInternal
! - Class
AStore
可以访问 publicA
成员,因为AInternal
继承了A
!