0

I'm not sure if my question is worded right, but I have a class that needs to make a property available to any class that instantiates it, but not make that property public. As an example:

public class MyClass1
{
    private double _PrivateNum = 9499488.07;
    private double PrivateNum
    {
        get
        {
            return _PrivateNum;
        }
    }
}

I want to create an instance of MyClass1 inside of MyClass2 and be able to access PrivateNum from MyClass2, but I don't want PrivateNum to be available outside of MyClass2. I know private double PrivateNum is not the correct, of course.

public class MyClass2
{ 
    public MyClass1 myclass1 = new MyClass1();

    public double GetSomeData
    {
        double PrivateNum = myclass1.PrivateNum;  <<== How do I set this in MyClass1
    }                                                  so I can access it in MyClass2,  
}                                                      but be unavailable outside
                                                       of MyClass2?

I just whipped up this example to illustrate what I'm wanting to accomplish. As I recall, VB uses shared to accomplish this. How is it done in C#?

rwkiii
  • 5,716
  • 18
  • 65
  • 114
  • Perhaps you want something like a [friend class](http://stackoverflow.com/questions/204739/what-is-the-c-sharp-equivalent-of-friend). – The Paramagnetic Croissant Aug 22 '14 at 19:33
  • 1
    What are you really trying to accomplish? Seems like a lot of hoops to jump through when any consuming class could easily make the value available to any other class. – tvanfosson Aug 22 '14 at 19:54
  • 1
    Your question doesn't make sense to me, because If you want to make the property available to _any_ class that instantiates it, it has to be public. Even if it's public it won't be available to other classes that don't instantiate it. What's the actual problem you are trying to solve? – Bryan Aug 22 '14 at 19:55
  • MyClass2 is a base product with a price (and lots of other product info). `MyClass1` contains information about options/accessories a user has chosen for the base product. Most times, the options/accessories price is intended to be displayed to the user for choices they have made for the product, but sometimes the option/accessory acts as a base price modifier. The requirement in these isolated cases is to deduct the option price from the base price, but the option price should not be seen or transmitted to the client. This class gets sent as Json so I don't want it publicly accessible. – rwkiii Aug 22 '14 at 20:18
  • @rwkiii I would suggest that a better way to handle it would be to expose a view (api) model that gets populated rather than your domain models. That way you can use the domain->api model mapping along with, perhaps separate, business logic calculators to populate the view model with exactly that data that should be exposed. – tvanfosson Aug 22 '14 at 20:56

4 Answers4

1

C# does not have the concept of friends as C++ does. A similar idea is internal though. If you mark the property as internal, only classes in the package can use it. Of course this requires your design allows putting MyClass1 and MyClass2 in the same package.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
0

There is no friend classes in C#. But if you want to expose data only to class which creates instance of MyClass1, then you can use ugly code with callback returned from MyClass1 constructor:

public class MyClass1
{
    private double _privateNum = 9499488.07;

    public MyClass1(out Func<double> callback)
    {
        callback = () => _privateNum;
    }

    // ...        
}

Now only class which instantiates MyClass1 instance will have access to this callback:

public class MyClass2
{
    private Func<double> callback;
    public MyClass1 myclass1;

    public MyClass2()
    {
        myclass1 =  new MyClass1(out callback);
    }

    public double GetSomeData()
    {
        double privateNum = callback();
        // ...
    }
}

And, of course, you always can use reflection and keep data private to all classes:

Type type = myclass1.GetType();
var flags = BindingFlags.Instance | BindingFlags.NonPublic;
var field = type.GetField("_privateNum", flags);
double privateNum = (double)field.GetValue(myclass1);
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • I understand your first example better and yes, it is ugly. The second example looks ugly to me too but probably because I don't comprehend reflection yet. Thank you, your first answer is an idea even though it's not the prettiest. – rwkiii Aug 22 '14 at 20:23
0

Couldn't you just make the variable protected in your MyClass1 and then just subclass MyClass1 with MyClass2?

efischency
  • 473
  • 2
  • 14
  • MyClass1 is actually a `` instantiated in MyClass2. I provided a better explanation in a comment to Bryan. – rwkiii Aug 22 '14 at 20:25
0

As I see from your comment, you don't want some data to be transferred to client. Its very easy to do - just map your MyClass2 objects to other class MyClass3 which do not have data you want to hide. You can use AutoMapper for that.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459