-1

I wish to call some methods only for the list of a class.

Although the extensive method could be defined only for List<>, it's not able to access the private field inside the target class (see code) because it is treated as a totally different class type.

I know in C++, friend could set some methods access to the private data. But C# can't

So, Is there any elegant pattern to share the private data between T and List?

e.g. :

class Solid
{ 
private Faces[] f;
...
}
public static class SolidExtensions
{
    public static Solid Merge(this IList<Solid> Solids)
     {
          //Get all faces from Solids. //not possible
           return Build(faces);
     }
}
Jianjie
  • 107
  • 5
  • 2
    Maybe `internal` might help you out ? otherwise you might reconsider an extension method and make marge a class member instead – TheGeneral Aug 31 '21 at 08:39
  • Private? No: [Properties vs fields](https://stackoverflow.com/questions/68042244/) • [Choose between private & protected members](https://stackoverflow.com/questions/58257849/#58258056) • [OOP](https://www.c-sharpcorner.com/UploadFile/mkagrahari/introduction-to-object-oriented-programming-concepts-in-C-Sharp) • [Classes](https://www.c-sharpcorner.com/UploadFile/84c85b/object-oriented-programming-using-C-Sharp-net) • [Abstraction](https://stackoverflow.com/questions/58765776/#58766026) • [Encapsulation](https://stackoverflow.com/questions/58257849/#58258056) –  Aug 31 '21 at 08:41
  • @TheGeneral Internal is a good idea. I just curious that is any idea available for explicitly separating the methods from different level of objects. – Jianjie Aug 31 '21 at 15:11

2 Answers2

1

I think this is your only way:

class Solid
{
    private Faces[] f;
    
    public static Solid Merge(IList<Solid> solids)
    {
        Faces[] faces = solids.SelectMany(x => x.f).ToArray();
        return Build(faces);
    }

    private static Solid Build(Faces[] faces)
    {
        throw new NotImplementedException();
    }
}

You'd call it as Solid.Merge(solids).

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • 1
    I think this solution is right. If your method needs to access private fields, it belongs to the class. – Mitko Petrov Aug 31 '21 at 11:03
  • Yes this is the method I am using. However, I think It should classified as "Utility" or "batch process". Use the static Merge may not follow some design principle? I think.. – Jianjie Aug 31 '21 at 15:10
  • The other choice is to use some sort of dependency injection framework and a factory method to create a private class, hidden behind an interface, that is able to access the private members. But that starts to get complicated. – Enigmativity Aug 31 '21 at 21:58
0

You'll have to make your array accessible from outside. If you don't want other classes to be able to modify your array, you can expose it as an IEnumerable<Faces>:

class Solid
{ 
    private Faces[] f;
    public IEnumerable<Faces> Faces
    {
        get { return f; }
    }
}

This is how you access it:

public static class SolidExtensions
{
    public static Solid Merge(this IList<Solid> Solids)
     {
           var allFaces = Solids.SelectMany(x => x.Faces);
           return Build(allFaces);
     }
}
SomeBody
  • 7,515
  • 2
  • 17
  • 33
  • thanks, the key problem is I want to keep Faces as private... – Jianjie Aug 31 '21 at 09:25
  • 1
    You want to keep `Faces` private, yet you want to access it? Then put `Merge` inside `Solid`. – Enigmativity Aug 31 '21 at 10:47
  • thank you, @Enigmativity . Sadly, I think the Merge is better to work over a group of solids, it's may not equivalent to work on single solid one by one. – Jianjie Aug 31 '21 at 15:07