由于C#不提供用于朋友函数和类的机制,如果我不将代码分发到单独的程序集中并且不能总是使用嵌套类,则内部关键字无济于事,我想到了:>
public sealed class FriendlyClass
{
private readonly string SecretKey = "MySecretKey";
public string PublicData { get; set; }
private string privateData;
public FriendlyClass()
{
PublicData = "My public data";
privateData = "My Private Data";
}
public string GetPrivateData(string key = null)
{
if (key == SecretKey)
return privateData;
else throw new System.InvalidOperationException("You can't call this method directly.");
return null;
}
public void SetPrivateData(string newData, string key = null)
{
if (key == SecretKey)
privateData = newData;
else throw new System.InvalidOperationException("You can't call this method directly.");
}
}
FriendlyClass friend = new FriendlyClass();
public void FriendlyMethod(string data)
{
friend.SetPrivateData(data, "MySecretKey");
}
public void StrangerMethod(string data)
{
friend.SetPrivateData(data);
}
FriendlyMethod("Data is changed");
StrangerMethod("Data is not changed");
这很丑陋而且要写很多东西。我的问题是:有人仍然可以滥用FriendlyClass的公共方法,使代码崩溃或产生意外行为吗?
答案 0 :(得分:1)
访问修饰符不应保证数据安全,而应确保代码质量并限制调用某些方法或访问某些数据的方式。但是,即使您创建了一个将所有字段和方法都标记为私有的类,仍有一些方法允许程序员从代码中的“未授权”位置访问这些成员。反射可以被认为是这些方法之一。以下面的代码为例:
public sealed class Example
{
private string field = "secure";
private void PrintField()
{
Console.WriteLine(this.field);
}
}
public class Program
{
public static void Main()
{
var example = new Example();
var field = example.GetType().GetField("field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var method = example.GetType().GetMethod("PrintField", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
field.SetValue(example, "hacked");
method.Invoke(example, new object[] { });
Console.ReadLine();
}
}
即使Example
类中的方法和字段都被标记为私有,Program
类中的调用者也可以否决该方法,并且都可以在字段中设置值并调用方法
所以我的答案是-是的,仍然有人可以通过使用Reflection,直接内存操作等来滥用它。如果有人想“入侵”您的代码-他们仍然会这样做。没有理由让没有这样做的人变得更加艰难。我认为使用这样的伪友好类会给程序员一种错误的安全感,但代价是代码清晰度降低和使用该类所需的不必要操作的代价很高。