只允许某些 类 编辑某些属性
Only allow certain classes to edit certain properties
我有一个 class,其中创建了一个 PictureBox,如下所示:
public class Tile
{
public PictureBox tilePB = new PictureBox(); //properties don't matter in this case
}
我还有一个 class GameManager。这就像裁判。
我想做到 Tile.tilePB 的 BackColor 只能由 Gamemanager 编辑,而不能由其他 class.
编辑
我目前有一个用于 Gamemanager(编辑)的 public PictureBox 和一个用于其他 classes 的 public get 函数,但我实际上想让它成为一个有效的系统我现在拥有的。
这可能吗?请包括所需代码的解释。
编辑:我 运行 遇到了一个我没有想到的问题:class Gamemanager 是静态的 class。我通过 public 静态函数完成 class 中的所有操作。这仍然可能吗?由于 this
不起作用。
不确定这是否正是您要找的,但我做了这个快速测试,它似乎能够区分调用 class:
class Program
{
static void Main(string[] args)
{
Type1 something1 = new Type1();
Type2 something2 = new Type2();
something1.runTest();
something2.runTest();
Console.ReadKey();
}
public class Type1
{
public void runTest()
{
Testing.edit(this);
}
}
public class Type2
{
public void runTest()
{
Testing.edit(this);
}
}
public static class Testing
{
public static void edit(object obj)
{
// This is where you test the calling class to make sure
// it is allowed to edit.
Console.WriteLine(obj.GetType().ToString());
}
}
}
你不能在编译时这样做,但它可以在运行时完成:
public class PictureBox
{
private Color _backColor;
public void SetBackColor(Color color)
{
//getting class type that called this method
var stackTrace = new StackTrace();
var stackFrames = stackTrace.GetFrames();
var callingFrame = stackFrames[1];
var method = callingFrame.GetMethod();
//checking if the class type is GameManager
if (!method.DeclaringType.IsAssignableFrom(typeof(GameManager)))
{
throw new FieldAccessException("Only GameManager can set the background color of a PictureBox!");
}
_backColor = color;
}
public Color BackColor => _backColor;
}
public class Tile
{
public PictureBox tilePB { get; set; }
}
//example GameManager class
public class GameManager
{
public void SetBackground()
{
var someTile = new Tile()
{
tilePB = new PictureBox()
};
var someColor = new Color();
someTile.tilePB.SetBackColor(someColor);
}
}
//example class that may want to set picturebox background color
public class MaliciousClass
{
public void SetBackground()
{
var someTile = new Tile()
{
tilePB = new PictureBox()
};
var someColor = new Color();
someTile.tilePB.SetBackColor(someColor);
}
}
然后某处:
var gm = new GameManager();
var mc = new MaliciousClass();
gm.SetBackground(); //this is fine
mc.SetBackground(); //this will throw an exception
如果你不想抛出异常或者你想在 "not authorized" class 尝试访问 SetBackColor
方法时做一些不同的事情,那么只需替换 throw new FieldAccessException()
与 return
或任何你想要的。
切记,这里介绍的方法效率低下,它只是表示可以在运行时完成,仅此而已。
我能想到的唯一方法是在编译时在哪里强制执行此操作,结果有点复杂。我认为你不会想要这样做。
您可以使用 properties/methods 创建一个接口,用于只允许 GameManager 执行的所有操作。您可以在 Tile
下面的私有内部 class 中实现此接口,并确保创建此对象的唯一方法是传入接收它的 GameManager。现在,访问可以 'leak' 的唯一方法是 GameManager 'gives away' 对象。
public class GameManager {
public void AddTile(Tile t, Tile.IManagerHook m) {
m.SomeProperty = "set from manager";
}
}
public class Tile
{
public object SomeProperty { get; private set; }
public Tile(GameManager manager) {
manager.AddTile(this, new ManagerHook(this));
}
public interface IManagerHook {
object SomeProperty {get; set;}
}
private class ManagerHook : IManagerHook {
private Tile _tile;
public ManagerHook(Tile t) {
_tile = t;
}
public object SomeProperty {
get{ return _tile.SomeProperty;}
set { _tile.SomeProperty = value; }
}
}
}
(好像)根本不可能
在询问了几位程序员之后,如果没有非常复杂的代码,我对所有内容和我想要的内容进行编码的方式似乎是不可能的 - 以至于你最好重构所有内容。由于 class Gamemanager 是静态的 class,因此不会有它的实例,因此您无法检查调用它的 'object' 是否属于 class Gamemanager。 this
也不起作用,因为 Gamemanager 是静态的。
我有一个 class,其中创建了一个 PictureBox,如下所示:
public class Tile
{
public PictureBox tilePB = new PictureBox(); //properties don't matter in this case
}
我还有一个 class GameManager。这就像裁判。
我想做到 Tile.tilePB 的 BackColor 只能由 Gamemanager 编辑,而不能由其他 class.
编辑我目前有一个用于 Gamemanager(编辑)的 public PictureBox 和一个用于其他 classes 的 public get 函数,但我实际上想让它成为一个有效的系统我现在拥有的。
这可能吗?请包括所需代码的解释。
编辑:我 运行 遇到了一个我没有想到的问题:class Gamemanager 是静态的 class。我通过 public 静态函数完成 class 中的所有操作。这仍然可能吗?由于 this
不起作用。
不确定这是否正是您要找的,但我做了这个快速测试,它似乎能够区分调用 class:
class Program
{
static void Main(string[] args)
{
Type1 something1 = new Type1();
Type2 something2 = new Type2();
something1.runTest();
something2.runTest();
Console.ReadKey();
}
public class Type1
{
public void runTest()
{
Testing.edit(this);
}
}
public class Type2
{
public void runTest()
{
Testing.edit(this);
}
}
public static class Testing
{
public static void edit(object obj)
{
// This is where you test the calling class to make sure
// it is allowed to edit.
Console.WriteLine(obj.GetType().ToString());
}
}
}
你不能在编译时这样做,但它可以在运行时完成:
public class PictureBox
{
private Color _backColor;
public void SetBackColor(Color color)
{
//getting class type that called this method
var stackTrace = new StackTrace();
var stackFrames = stackTrace.GetFrames();
var callingFrame = stackFrames[1];
var method = callingFrame.GetMethod();
//checking if the class type is GameManager
if (!method.DeclaringType.IsAssignableFrom(typeof(GameManager)))
{
throw new FieldAccessException("Only GameManager can set the background color of a PictureBox!");
}
_backColor = color;
}
public Color BackColor => _backColor;
}
public class Tile
{
public PictureBox tilePB { get; set; }
}
//example GameManager class
public class GameManager
{
public void SetBackground()
{
var someTile = new Tile()
{
tilePB = new PictureBox()
};
var someColor = new Color();
someTile.tilePB.SetBackColor(someColor);
}
}
//example class that may want to set picturebox background color
public class MaliciousClass
{
public void SetBackground()
{
var someTile = new Tile()
{
tilePB = new PictureBox()
};
var someColor = new Color();
someTile.tilePB.SetBackColor(someColor);
}
}
然后某处:
var gm = new GameManager();
var mc = new MaliciousClass();
gm.SetBackground(); //this is fine
mc.SetBackground(); //this will throw an exception
如果你不想抛出异常或者你想在 "not authorized" class 尝试访问 SetBackColor
方法时做一些不同的事情,那么只需替换 throw new FieldAccessException()
与 return
或任何你想要的。
切记,这里介绍的方法效率低下,它只是表示可以在运行时完成,仅此而已。
我能想到的唯一方法是在编译时在哪里强制执行此操作,结果有点复杂。我认为你不会想要这样做。
您可以使用 properties/methods 创建一个接口,用于只允许 GameManager 执行的所有操作。您可以在 Tile
下面的私有内部 class 中实现此接口,并确保创建此对象的唯一方法是传入接收它的 GameManager。现在,访问可以 'leak' 的唯一方法是 GameManager 'gives away' 对象。
public class GameManager {
public void AddTile(Tile t, Tile.IManagerHook m) {
m.SomeProperty = "set from manager";
}
}
public class Tile
{
public object SomeProperty { get; private set; }
public Tile(GameManager manager) {
manager.AddTile(this, new ManagerHook(this));
}
public interface IManagerHook {
object SomeProperty {get; set;}
}
private class ManagerHook : IManagerHook {
private Tile _tile;
public ManagerHook(Tile t) {
_tile = t;
}
public object SomeProperty {
get{ return _tile.SomeProperty;}
set { _tile.SomeProperty = value; }
}
}
}
(好像)根本不可能
在询问了几位程序员之后,如果没有非常复杂的代码,我对所有内容和我想要的内容进行编码的方式似乎是不可能的 - 以至于你最好重构所有内容。由于 class Gamemanager 是静态的 class,因此不会有它的实例,因此您无法检查调用它的 'object' 是否属于 class Gamemanager。 this
也不起作用,因为 Gamemanager 是静态的。