1

I'm not very familiar with C# and I've not been able to find a reasonable answer anywhere. I simply want to return an object from a function that to the caller is opaque. I still want the user to be able to pass the object around, I just don't really want them calling any of the methods on the object.

In C++, you'd simply return a void* and then a function receiving that object would cast it to its appropriate type and call the methods on it.

public class Blob
{
    public void Method1() { do_something(); }
    public void Method2() { do_something_else(); }
}

public class BlobMaker
{
    public Blob CreateBlob() { return new Blob(); }  // This needs to return something opaque
}

public class BlobUser
{
    public void ConsumeBlob(var b)   // Method would take the opaque type
    {
        Blob newBlob = (Blob)b;
        b.Method1();
        b.Method2();
    }
}

public class MainApp
{
    BlobMaker m = new BlobMaker();
    var obj = m.CreateBlob();        //  obj returned by BlobMaker should be opaque.

    obj.Method1();                   //  This should not be allowed
    obj.Method2();                   //  This should not be allowed

    BlobUser user = new BlobUser();
    user.ConsumeBlob(obj);

}

In my case, I simply don't want to completely trust the user to have access to the Blob methods, so I want the object to be opaque. In the Win32 API this is done all the time with all sorts of Windows structures being opaque as void* pointers.

Now I know that you can use "unsafe" and probably do exactly the same thing in C#, but I was wondering if there was a better way in C# to do this?

** EDIT ** Just ignore me people.... I'm being a loony... the answer is simple. All that method has to do is return object instead of Blob and it done. Sorry people, it was a certified brain fart.

The Welder
  • 916
  • 6
  • 24
  • If I understand correctly, you want `object obj = new Blob();`? – Sweeper Jun 26 '21 at 03:22
  • I am not good at `opaque`, but why do you need to create an object in `MainApp`, why can't you create it inside `ConsumeBlob()` function itself. Or if you want to pass object from parent function to `ConsumeBlob()` then use `dynamic` or `object` while declaring the function – Prasad Telkikar Jun 26 '21 at 03:26
  • @Sweeper Yes, you could do an object obj = new Blob(), the problem is that it still doesn't stop the user doing: Blob obj = new Blob(). I want obj to be an opaque type, not simply opaque because you've declared it to be of type object. – The Welder Jun 26 '21 at 03:27
  • @PrasadTelkikar I could create it inside ConsumeBlob, but I need the user to be able to pass the object around to other functions, not just ConsumeBlob(). So BlobUser may contain many methods and they may pass it to many or just one method. – The Welder Jun 26 '21 at 03:30
  • "the problem is that it still doesn't stop the user doing: Blob obj = new Blob()" Well how does C++ stop the user from doing `Blob *obj = new Blob();` then? – Sweeper Jun 26 '21 at 03:33
  • In C++, you'd do it with a typedef void*. Let me see if I can rephrase the question because people aren't really getting what I'm asking.... – The Welder Jun 26 '21 at 03:36
  • Ah ok, why not just make `BlobMaker.CreateBlob` return an `object` then? If you don't even want anyone else other than `BlobUser` to know the _existence_ of `Blob`, you can put both `BlobUser` and `Blob` _inside_ `BlobMaker`, and mark them `private`. – Sweeper Jun 26 '21 at 03:49
  • Do you know.... About 30 seconds before you typed your answer, my brain said to me.... "You are being a loony, why don't you just make the method return object". And was just about to say that I'd solved it when your answer popped up... Muahahahahha. Thanks. – The Welder Jun 26 '21 at 03:51
  • Even if you make `Blob` private and return `object`, it is still possible to call the `Blob` methods using reflection. If you want to defend against this as well, you should run the "blob maker" in a separate process and communicate using some kind of IPC/message passing mechanism. – JosephDaSilva Jun 26 '21 at 04:41
  • @JosephDaSilva Yes, of course and I'm not trying to make it completely impossible. You can always do something like that, or if you know the object's type, you can cast it appropriately. I was just after a way of making it fairly obvious that I don't want you calling the methods on this object and it should be left alone as considered to be a Blob rather than a class. – The Welder Jun 26 '21 at 12:02

0 Answers0