只允许某些 类 编辑某些属性

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 是静态的。