开发者

Limiting access to a public setter to specific objects (C#)

开发者 https://www.devze.com 2023-01-19 19:36 出处:网络
I\'m trying to create a class (in C#) that serves as an environment for my application. I\'m trying to make the class dynamic, and send it as a parameter to entities in my application. The problem is

I'm trying to create a class (in C#) that serves as an environment for my application.

I'm trying to make the class dynamic, and send it as a parameter to entities in my application. The problem is, that I want to be able to change the properties of this environment class (public setters), but at the same time I want the classes that receive the environment to be unable to use these setters.

I can't seem to find a good way to 开发者_开发问答phrase my question (which I figure is a part of the reason I can't find anything like this on Google or msdn), but to put shortly, I want to create a class with setters that are public only for some of my objects and not for all.

I'm currently amusing the following idea: Avoiding the public setters all together, and expose the private fields using event registration.

The class will register to events in a new third object (sent as a parameter to the constructor). The methods that will be registered by the environment are not much more then setters, and so triggering these events will "allow access" to the private fields.

I'd love some ideas (seeing as I feel that mine isn't all that great), or better yet some patterns I could make use of.

Thanks in advance


Isn't "internal" sufficient for what you need?

And you could move the setters into an interface as explicit implementation. Then they are hidden from the public interface and only accessible if you cast to the interface.

And if you want to make really sure that nobody else can call it you can add some parameter to these functions where you expect a certain token object which you only give to trusted classes.

void SetX(int value, object token)
{
    if(token!=correctToken)
        throw new ArgumentException("wrong token");
    x=value;
}


You could create a proxy, and send that proxy to your entity classes.

class MyClass
{
    public int MyProperty { get; set; }
}

class MyProxyClass
{
    public MyProxyClass(MyClass myClass)
    {
        _myClass = myClass;
    }

    private MyClass _myClass;

    public int MyProperty
    {
        get { return _myClass.MyProperty; }
    }
}


You could try using Friend assemblies. That will allow only the assemblies you specify to have access to your privates (snicker).


Maybe i understood something not quite well, but i think Jon had a quite similar problem which he described here. Maybe this can help you.


How about

class Callee
{
    public void SetX(TypeOfCaller caller, int value)
    {
    }
}
class TypeOfCaller
{
    public void Do()
    {
        Callee instance;
        //..
        instance.SetX(this, 5);
    }
}

Doing so; you can also use Visual Studio' Find References feature! In case you want multiple types of caller; you can either opt for class hierarchy or can simply have required overloads


Why not return clones of your protected objects instead of the actual objects? Solves the problem without adding any more complexity.

public class MyService
{
    private List<MyObject> _protectedObjects = new List<MyObject>();

    public MyObject GetItem(int id)
    {
        return (MyObject)_protectedObjects.First(i => i.Id == id).Clone();
    }
}

public class MyObject : ICloneable
{
     //[...]
     public object Clone()
     {
         return MemberwiseClone();
     }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号