Class 访问者级别 - 如何做到这一点?
Class accessor level - how to make this possible?
我遇到这种情况:我需要 class2(string)
构造函数只能从 class1
方法内部访问,而不是从外部 classes:
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()
创建用户的空实例 class 而 class2(...)
登录用户。现在我有 class1 可以从我的页面调用的登录方法访问权限,我不希望我的任何页面直接调用我的 class2(...)
登录但必须全部从 class1.access()
传递 returns class2
与用户信息。
编辑:这样做的目的是创建一个安全的登录程序,我不想公开我的登录信息并使其可以直接从我的页面访问,我希望我的页面从 class1.access()
的逻辑传递,这将考虑 how/if 以登录用户和 return 并且如果登录失败也为 class2.valid=false;
或空 class2
将 return a class2
包含来自用户的所有信息。我需要从我的页面访问、创建和清空 class2
,因为我在我的 class1.access(login_credentials credentials, out class2 user_data)
中将它作为 out
参数传递
你不能用普通的构造(使用访问修饰符)做到这一点,但你可以做到的一种方法是反射:
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
它获取对象的引用并将其转换为强类型。
据我所知,没有 direct 机制来限制对嵌套 class 的构造函数的访问仅限于其包装 class。尽管您可以考虑一些代码重新设计的解决方法。如果你愿意,你可以使构造函数 internal
:
public class class1
{
public void access()
{
var c = new class2("asdf");
}
public class class2
{
public class2()
{
}
internal class2(string p)
{
}
}
}
这将限制对 class2
所在的 assembly 的构造函数的访问。如果您只想限制 第三方 使用您的库的访问权限,那么这可能是一个可行的解决方案。
另一种选择是您可以利用嵌套 class2
可以访问 class1
的 private
成员这一事实。通过这种方式,您可以将工厂方法提升为 "expose" 构造函数:
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
是 只有 类型可以访问 class2(string p)
构造函数。我认为你最好的选择是考虑对你的代码设计进行可能的更改。
在这种情况下我会使用接口。毕竟界面正是您所描述的。
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";
}
}
}
}
结果:
True
False
您可以传递您的 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");
我遇到这种情况:我需要 class2(string)
构造函数只能从 class1
方法内部访问,而不是从外部 classes:
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()
创建用户的空实例 class 而 class2(...)
登录用户。现在我有 class1 可以从我的页面调用的登录方法访问权限,我不希望我的任何页面直接调用我的 class2(...)
登录但必须全部从 class1.access()
传递 returns class2
与用户信息。
编辑:这样做的目的是创建一个安全的登录程序,我不想公开我的登录信息并使其可以直接从我的页面访问,我希望我的页面从 class1.access()
的逻辑传递,这将考虑 how/if 以登录用户和 return 并且如果登录失败也为 class2.valid=false;
或空 class2
将 return a class2
包含来自用户的所有信息。我需要从我的页面访问、创建和清空 class2
,因为我在我的 class1.access(login_credentials credentials, out class2 user_data)
out
参数传递
你不能用普通的构造(使用访问修饰符)做到这一点,但你可以做到的一种方法是反射:
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
它获取对象的引用并将其转换为强类型。
据我所知,没有 direct 机制来限制对嵌套 class 的构造函数的访问仅限于其包装 class。尽管您可以考虑一些代码重新设计的解决方法。如果你愿意,你可以使构造函数 internal
:
public class class1
{
public void access()
{
var c = new class2("asdf");
}
public class class2
{
public class2()
{
}
internal class2(string p)
{
}
}
}
这将限制对 class2
所在的 assembly 的构造函数的访问。如果您只想限制 第三方 使用您的库的访问权限,那么这可能是一个可行的解决方案。
另一种选择是您可以利用嵌套 class2
可以访问 class1
的 private
成员这一事实。通过这种方式,您可以将工厂方法提升为 "expose" 构造函数:
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
是 只有 类型可以访问 class2(string p)
构造函数。我认为你最好的选择是考虑对你的代码设计进行可能的更改。
在这种情况下我会使用接口。毕竟界面正是您所描述的。
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";
}
}
}
}
结果:
True
False
您可以传递您的 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");