我遇到这种情况:我需要class2(string)
构造函数只能从class1
方法中访问,而不能从外部类访问:
public class class1
{
public void access()
{
//want to make class2(string) be accessible only from here
}
public class class2
{
public class2()
{
}
private class2(string p)
{
}
}
}
我试图验证用户,class2()
在class2(...)
登录用户时创建用户类的空实例。现在我有可以从我的页面调用的class1登录方法访问,我不希望我的任何页面直接调用我的class2(...)
登录,但必须全部从class1.access()
传递,返回{{1}用户信息。
编辑:这样做的目的是创建一个安全的登录程序,我不希望公开我的登录并直接从我的页面访问它,我希望我的页面从逻辑中传递class2
的{{1}}将考虑如何/如果登录用户并返回并清空class1.access()
如果登录失败并同时class2
或将返回class2.valid=false;
所有来自用户的信息。我需要在我的网页中访问并创建并清空class2
,因为我在class2
out
param传递
答案 0 :(得分:2)
据我所知,没有直接机制将访问嵌套类的构造函数限制为仅包装类。您可以考虑使用几种代码重新设计的解决方法。如果您愿意,可以创建构造函数internal
:
public class class1
{
public void access()
{
var c = new class2("asdf");
}
public class class2
{
public class2()
{
}
internal class2(string p)
{
}
}
}
这将限制对class2
所在的程序集的构造函数的访问。如果您只想限制第三方使用您的库的访问权限,那么这可能是一个可行的解决方案。
另一个选择是,您可以利用嵌套class2
可以访问private
class1
成员的事实。通过这种方式,您可以提升工厂方法来“公开”构造函数:
public class class1
{
private static Func<string, class2> CreateNewClass2;
static class1()
{
//this just forces the static constructor on `class2` to run.
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(class2).TypeHandle);
}
public void access()
{
class2 c = CreateNewClass2("asdf");
}
public class class2
{
static class2()
{
//this is where we create a delegate exposing/promoting our private constructor
class1.CreateNewClass2 = p => new class2(p);
}
public class2()
{
}
private class2(string p)
{
}
}
}
老实说,这有点迟钝,但它会强制执行规则,以便class1
和class2
是唯一的类型,可以访问{ {1}}构造函数。我认为你最好的选择是考虑改变你的代码设计。
答案 1 :(得分:1)
你不能用普通结构(使用访问修饰符)来做,但你能做到的一种方法是使用反射:
public class Outer
{
public Inner GetInstanceOfInner(string s)
{
var innerInstance =
typeof(Inner).GetConstructor(
System.Reflection.BindingFlags.NonPublic, //Search for private/protected
null, //Use the default binder
new[] { typeof(string) }, //Parameter types in the ctor
null) //Default binder ignores this parameter
.Invoke(new[] { s }) as Inner; //Create and cast
return innerInstance;
}
public class Inner
{
public Inner() { }
private Inner(string s) { }
}
}
使用反射,您可以使用BindingFlags.NonPublic
调用私有或受保护的构造函数来查找适当的构造函数。之后你.Invoke
获取对象的引用并将其强制输入。
答案 2 :(得分:1)
我会在这个实例中使用一个接口。毕竟,界面正是您所描述的。
using System;
public class Program
{
// Properties you want others to have access too
public interface ICredentialsValidator
{
bool IsTest(string userName);
}
public static void Main()
{
var b = new PublicClass().GetCredentialsValidator();
Console.WriteLine(b.IsTest("test"));
Console.WriteLine(b.IsTest("blah"));
}
public class PublicClass
{
public ICredentialsValidator GetCredentialsValidator()
{
return new PrivateClass();
}
private class PrivateClass : ICredentialsValidator
{
public bool IsTest (string userName)
{
return userName == "test";
}
}
}
}
结果:
真
假
您可以传递ICredentialsValidator
,但没有人可以创建ICredentialsValidator
或class2
。简单的OOP。
虽然我发现这非常复杂且过于复杂。我只想使用单例模式和Liskov's Substitution Principle的接口:
public interface ISecurity
{
bool IsTest(string userName);
}
public sealed class Security : ISecurity
{
private static readonly Lazy<Security> lazy =
new Lazy<Security>(() => new Security());
public static ISecurity Security Instance { get { return lazy.Value; } }
private Singleton()
{
}
public bool IsTest(string userName)
{
}
}
然后任何人都会
Security.Instance.IsTest("test");