Public and Internal members in an Internal class? - c#

Ok, so this may be a bit of a silly question, and there's certainly the obvious answer, but I was curious if I've missed any subtleties here.
Is there any difference in terms of visibility/usability between a public member declared in an internal class and an internal member declared in an internal class?
i.e. between
internal class Foo
{
public void Bar()
{
}
}
and
internal class Foo
{
internal void Bar()
{
}
}
If you declared the method as public and also virtual, and then overrode it in a derived class that is public, the reason for using this modifier is clear. However, is this the only situation... am I missing something else?

Consider this case:
public interface IBar { void Bar(); }
internal class C : IBar
{
public void Bar() { }
}
Here C.Bar cannot be marked as internal; doing so is an error because C.Bar can be accessed by a caller of D.GetBar():
public class D
{
public static IBar GetBar() { return new C(); }
}
A commenter asked a follow-up question: is an explicit implementation of an interface method considered to be public, or private? (C# does not allow you to put an access modifier on an explicit implementation.)
Take a step back and think about what exactly is "public" or "private" about a member: people think wrong things like "private means that a method cannot be called from outside the class", but that's not true; the class could make a delegate to a private method, pass it to anyone, and they can then call a private method.
Rather, accessibility determines where the name of a thing can be used! Explicit interface implementations do not add a name to the class declaration space in the first place; they can only be referred to by name via the interface, not the class. It really doesn't make sense to think of explicit interface implementations as public or private because they don't have a name you can refer to.

A public member is still just internal when in an internal class.
From MSDN:
The accessibility of a member can never be greater than the accessibility of its containing type. For example, a public method declared in an internal type has only internal accessibility
Think of it this way, I would access a public property on....? A class I can't see? :)
Eric's answer is very important in this case, if it's exposed via an interface and not directly it does make a difference, just depends if you're in that situation with the member you're dealing with.

public members of an internal class can override public members of public base classes and, therefore, be a little more exposed... if indirectly.

Just faced with another example where there is difference between those two, when used from XAML in WPF.
XAML:
<Button Tag="{x:Static vm:Foo+Bar.e1}" />
Code with internal enum compiles successfully:
internal class Foo
{
internal enum Bar
{
e1,
e2,
}
}
But surprisingly changing it to public results in error:
internal class Foo
{
public enum Bar
{
e1,
e2,
}
}
The last example produces compilation error:
error MC3064: Only public or internal classes can be used within markup. 'Bar' type is not public or internal.
Unfortunately, I can't explain what's wrong with public in this case. My guess is "just because WPF works that way". Just change modifier of the nested class to internal to get rid of error.

If it comes to reflection it matters if the member is public or not:
For example you even could pass a nested private class to a WPF binding and the binding would work against the public properties just as usual.

Related

Abstract method in public abstract class implementing an internal interface doesn't compile?

internal interface I_Foo
{
void Bar();
}
public abstract class A_Foo : I_Foo
{
public A_Foo() { }
abstract void I_Foo.Bar();
}
public class Foo : A_Foo
{
public Foo() : base() { }
internal override void Bar()
{
}
}
Hello! I'm trying to have some methods visible to outside code, and other only visible to my assembly. For this purpose, I made an internal interface I_Foo to serve as a contract to other parts of the assembly, a public abstract A_Foo to serve as abstraction for external code, and centralize some constructor functionality, and several different classes Foo that implement A_Foo and I_Foo explicitly to retain internal modifier.
However, in the A_Foo class, I get
'A_Foo.I_Foo.Bar()' must declare a body because it is not marked abstract, extern, or partial
even though the method is clearly marked as "abstract". If I add a body, I get "abstract is not a valid modifier".
I need this method to be explicitly declared, in order to be internal in a public class, and I need it to be abstract so I can override it in the actual implementation Foo.
Why doesn't the compiler let me?
Is there another way I can achieve the same thing?
Thank you.
Explicit interface implementations always have to have an actual implementation. The trick here is to making that just call a non-explicit (internal) abstract method:
public abstract class A_Foo : I_Foo
{
// Classes outside the assembly can't derive from A_Foo
// anyway, so let's make the constructor internal...
internal A_Foo() { }
void I_Foo.Bar()
{
Bar(); // Just delegate to the abstract method
}
internal abstract void Bar();
}
This still allows I_Foo to use internal types etc, because Bar is never exposed publicly - but it fits within the other rules of the language.
The method can not be abstract. THe problem is that you try to use explicit interface implementation (void I_Foo.Bar). Those methods can not be overwritten later - so they have to be implemented.
If you declare Bar directly (void Bar()) then it can be abstract.

Compiler says I am not implementing my interface, but I am?

Okay, I have two namespaces. One contains my interface and one contains the implementing class. Like this:
namespace Project.DataAccess.Interfaces
{
public interface IAccount
{
string SomeMethod();
}
}
namespace Project.DataAccess.Concrete
{
class Account : Project.DataAccess.Interfaces.IAccount
{
string SomeMethod()
{
return "Test";
}
}
}
With this code I get an error:
'Project.DataAccess.Concrete.Account' does not implement interface member 'Project.DataAccess.Interfaces.IAccount.SomeMethod'. 'Project.DataAccess.Concrete.Account.SomeMethod' cannot implement an interface member because it is not public
If I make the class and method public it works fine. But if I instead qualify the method name with the interface name, that fixes it too. Why? Ex:
namespace Project.DataAccess.Concrete
{
class Account : Project.DataAccess.Interfaces.IAccount
{
string IAccount.SomeMethod()
{
return "Test";
}
}
}
Why does this fix it? And why does it have to be public if I don't do that?
To be clear
I am well aware that making it public fixes it. Making the method signature look like this WITHOUT making anything public fixes it:
string IAccount.SomeMethod()
Why?
Interface implementations need to be public or explicit:
Public:
class Account : IAccount
{
public string SomeMethod()
{
return "Test";
}
}
Explicit:
class Account : IAccount
{
string IAccount.SomeMethod()
{
return "Test";
}
}
The default access modifier in C# is private if you do not specify the access modifier.
You have 2 basic options when implementing intefaces: implicit or explicit. Implicit implementation takes on the form of a public method or property, while explicit is in the form of a method or property prefaced with the IFoo. modifier that is otherwise not public.
interface IFoo
{
void Bar();
}
class FooA : IFoo
{
public void Bar() { }
}
class FooB : IFoo
{
void IFoo.Bar() { }
}
The difference here is that in the case of FooA, void Bar is part of the publicly visible API of the class. Code can call Bar via the instance of the class.
FooA foo = new FooA();
foo.Bar(); // legal
In the case of FooB, void Bar is not part of the publicly visible API of the class. The method can still be called, but it must explicitly be called via the interface.
FooB foo = new FooB();
foo.Bar(); // not legal
IFoo myFoo = foo;
myFoo.Bar(); // legal
Your code does not compile because it walks in the uncharted waters between an implicit and explicit interface implementation. You saw that with your change, you had legally defined an explicit implementation, which is why that particular version compiles. Otherwise, you've also found that the public modifer is needed to make the non-explicit version compile.
Methods implementing interface needs to be public. In your later case, you are declaring it explicitly. This is what specification says about explicit interface implementation.
Explicit interface member
implementations have different
accessibility characteristics than
other members. Because explicit
interface member implementations are
never accessible through their fully
qualified name in a method invocation
or a property access, they are in a
sense private. However, since they can
be accessed through an interface
instance, they are in a sense also
public.
'Project.DataAccess.Concrete.Account.SomeMethod' cannot implement an interface member because it is not public
namespace Project.DataAccess.Concrete
{
public class Account : IAccount
{
public string IAccount.SomeMethod()
{
return "Test";
}
}
}
You're not mentioning in your class declaration that you'll be implementing IAccount.
Your class declaration should look like this:
class Account : IAccount
{
//Implementation here.
}
Also, what's happening is that you're using the "default" protection level for Account, and that protection level isn't "public", but an Interface (IAccount) defines public methods by default.
So, when you preface both the Class and Method names with public you're actually implementing the interface. Likewise, when you declare SomeMethod as
IAccount.SomeMethod()
{
//Implementation Here
}
what you're doing is Explicitly Implementing the interface.
I think declaring it explicitly with string IAccount.SomeMethod() works because .NET knows that this implementation of the method can only be accessed through the interface, and so it carries over the public visibility from the interface. In other words, since you are explicitly saying it is an interface member, the compiler can imply that it has to be public, so you don't have to re-state the obvious.
This is also discussed here: http://msdn.microsoft.com/en-us/library/aa664591%28v=vs.71%29.aspx
It is a compile-time error for an
explicit interface member
implementation to include access
modifiers, and it is a compile-time
error to include the modifiers
abstract, virtual, override, or
static.
Explicit interface member
implementations have different
accessibility characteristics than
other members. Because explicit
interface member implementations are
never accessible through their fully
qualified name in a method invocation
or a property access, they are in a
sense private. However, since they can
be accessed through an interface
instance, they are in a sense also
public.
class Account : IAccount
{
public string SomeMethod()
{
return "Test";
}
}
Tell your class to implement the interface. Using the Interface.Method name explicitly implements the method (but i'm not sure why or how) and you need to make them public.
You want to use Interface.Method to explicitly implement an interface requirement when the class already has a member of the same name
class MyClass : IAccount
{
public int SomeMethod() {}
public string IAccount.SomeMethod() {}
}

What is the meaning of a delegate inside a class?

I understand delegates as a shortcut for defining a class with one method but what is the meaning of bar2 below? It compiles. But I can't see what an inner class would do here. I know I'm missing something so that's why I'm asking (this is not homework, I'm at work-work right now).
namespace ns2 { public delegate void bar();}
public class foo
{
private ns2.bar _callback;
public foo(ns2.bar callback) { _callback = callback; }
public void baz() { _callback(); }
public delegate void bar2();
}
Thanks!
To add to Jon and Jared's answers, I note that the only time you'd usually define a delegate inside a class is if the delegate were a private implementation detail of the class. It is rare and bizarre to have a public delegate definition inside a class.
For example, consider my favourite pattern: an abstract base class that can only be extended by private nested classes that are manufactured with factories:
public abstract class Animal
{
private Animal() { } // prevents subclassing from outside!
private sealed class Giraffe : Animal { }
private sealed class Leopard : Animal { }
public static Animal GetGiraffe( ) { return new Giraffe(); }
public static Animal GetLeopard( ) { return new Leopard(); }
Suppose an implementation detail of Animal was that you needed to have a delegate from Giraffe to Leopard:
private delegate Leopard D(Giraffe g);
This cannot be a public delegate class because it refers to private types!
Nowadays of course you wouldn't even do this. You'd use Func<Giraffe, Leopard> and you're done.
Therefore, the nested delegate type is pretty much there for completeness and backwards compatibility these days; normally you wouldn't use it.
Delegates are not shortcuts for defining a class with one method. They in fact have at a minimum 6 methods (Invoke, BeginInvoke, EndInvoke, GetHashCode, Equals, ToString).
One reason for the pattern of putting delegates inside a type is to avoid global namespace pollution. The delegate bar2 is only accessible through a qualified reference from foo. This can be valuable if bar2 is a name which has multiple valid meannings and putting it within foo provides necessary context.
It's just declaring a nested type, that's all. As it's public, there's pretty much no difference between that being declared inside the type and being declared outside.
Other classes will have to refer to it via the name of the containing type (unless they have a using directive specifically for it):
public class OtherClass
{
private void DoSomething()
{
foo.bar2 action = delegate { ... };
foo f = new foo(action);
...
}
}
Usually when I write a nested type, it's private - it's just a helper class for the containing class; an implementation detail. That doesn't have to be the case, of course, but it should at least be true that the nested type is meaningless unless you're in some way using the outer class. For example, it could be a builder for the outer class, or an enum used in some parameters for a method call within the outer class.
(By the way, it's useful when writing sample code like this to follow .NET naming conventions even for meta-syntactic names like Foo and Bar. It makes the difference between variables and types clearer, for example.)

C# static member "inheritance" - why does this exist at all?

In C#, a superclass's static members are "inherited" into the subclasses scope. For instance:
class A { public static int M() { return 1; } }
class B : A {}
class C : A { public new static int M() { return 2; } }
[...]
A.M(); //returns 1
B.M(); //returns 1 - this is equivalent to A.M()
C.M(); //returns 2 - this is not equivalent to A.M()
Now, you can't inherit static classes, and the only place I can imagine that static inheritance might matter ignores it entirely: although you can make a generic constraint that requires a type parameter T to be a subclass of A, you still cannot call T.M() (which probably simplifies things for the VM), let alone write a different M implementation in a subclass and use that.
So, the "inheritance" of static members merely looks like namespace pollution; even if you explicitly qualify the name (i.e. B.M) A's version is still resolved.
Edit compare with namespaces:
namespace N1{ class X(); }
namespace N1.N2 { class X(); }
namespace N1.N2.N3 { [...] }
Within N1.N2.N3 It makes sense that if I use X without qualification it refers to N1.N2.X. But if I explicitly refer to N1.N2.N3.X - and no such class exists - I don't expect it to find N2's version; and indeed to compiler reports an error if you try this. By contrast, if I explicitly refer to B.M(), why doesn't the compiler report an error? After all, there's no "M" method in "B"...
What purpose does this inheritance have? Can this feature be used constructively somehow?
So, the "inheritance" of static
members merely looks like namespace
pollution
That's right, except that one guy's pollution is another guy's added spicy flavouring.
I think Martin Fowler, in his work on DSLs, has suggested using inheritance in this way to allow convenient access to static methods, allowing those methods to be used without class name qualification. So the calling code has to be in a class that inherits the class in which the methods are defined. (I think it's a rotten idea.)
In my opinion, static members should not be mixed into a class with a non-static purpose, and the issue you raise here is part of the reason why it's important not to mix them.
Hiding private static mutable data inside the implementation of an otherwise "instancey" class is particularly horrible. But then there are static methods, which are even worse mixers. Here's a typical use of static methods mixed into a class:
public class Thing
{
// typical per-instance stuff
int _member1;
protected virtual void Foo() { ... }
public void Bar() { ... }
// factory method
public static Thing Make()
{
return new Thing();
}
}
It's the static factory method pattern. It's pointless most of the time, but even worse is that now we have this:
public class AnotherThing : Thing { }
This now has a static Make method which returns a Thing, not a AnotherThing.
This kind of mismatch strongly implies that anything with static methods should be sealed. Static members fail to integrate well with inheritance. It makes no sense to have them heritable. So I keep static things in separate static classes, and I gripe about redundantly having to declare every member static when I've already said that the class is static.
But it's just one of those too-late-now things. All real, working languages (and libraries, and products) have a few of them. C# has remarkably few.
I rather have access to all my based static members in derived classes.
Otherwise i would need to know exactly where the static member was defined and call it explicitly.
When using Intellisense you can automatically know every static member available to that kind of class.
Of course, they are not inherited, it's just a shortcut
That's how it works, would probably just be a stupid answer in most cases. But in this case, it is how it works; since you derive from A you say that you are A + the extra features you add.
Therefore you need to be able to access the same variables that you would through an instance of A.
However, inheriting a static class makes no sense while access to the static members / fields / methods does.
An example of this is the following:
internal class BaseUser
{
public static string DefaultUserPool { get; set; }
}
internal class User : BaseUser
{
public int Id { get; set; }
public string Name { get; set; }
public User Parent { get; set; }
}
Where the test looks like this:
User.DefaultUserPool = "Test";
BaseUser.DefaultUserPool = "Second Test";
Console.WriteLine(User.DefaultUserPool);
Console.WriteLine(BaseUser.DefaultUserPool);
Both of the WriteLines outputs "Second Test", this is because both BaseUser and User should use DefaultUserPool, by design. And overriding static implemented methods wouldn't make mucn sense since it's just an accessor in the child-class.
There can be only one. Overriding it would mean that there's a new implementation for that sub-class, which would kill the term "static".
Actually, as I understand it, this is just a shortcut provided by the compiler. Syntax sugar. B.M() will just compile to A.M() since B does not have a static M() and A does. It's for easier writing, nothing else. There is no "static inheritance".
Added: And the requirement for new when "redefining" is just so that you don't accidentally shoot yourself in the foot.
I think it's for accessing protected static members of the base class.
class Base
{
protected static void Helper(string s)
{
Console.WriteLine(s);
}
}
class Subclass : Base
{
public void Run()
{
Helper("From the subclass");
}
}
So... What's the alternative?
The question mentions...
why doesn't the compiler report an error? After all, there's no "M" method in "B"...
But there is a derived "M" method in "B" class.
If the compiler did not present the programmer a unified virtual table for base cases, then the programmer would have to go hunting through base types to find static methods. This would break polymorphism.
Wikipedia...
Subtype polymorphism, almost universally called just polymorphism in the context of object-oriented programming, is the ability of one type, A, to appear as and be used like another type, B....
In strongly typed languages, polymorphism usually means that type A somehow derives from type B, or type C implements an interface that represents type B.
I always see it a means of preventing any form of polymorphism by the inheriting class on those items that you wish to retain the same function for all child classes.
ignore the above for some reason I was thinking of sealed instead of static
I suppose that you'd use static member variables and functions in order to ensure that any data or functionallity is not dependent on the a class instance as it would be instantiated only the once.
An example of use would be say a counter value that would keep a live count of all instances of a superclass's subclasses (each subclass increments the static count value on construction). This count value would be available and equal for all instances of the subclass.

C#, implement 'static abstract' like methods

I recently ran into a problem where it seems I need a 'static abstract' method. I know why it is impossible, but how can I work around this limitation?
For example I have an abstract class which has a description string. Since this string is common for all instances, it is marked as static, but I want to require that all classes derived from this class provide their own Description property so I marked it as abstract:
abstract class AbstractBase
{
...
public static abstract string Description{get;}
...
}
It won't compile of course. I thought of using interfaces but interfaces may not contain static method signatures.
Should I make it simply non-static, and always get an instance to get that class specific information?
Any ideas?
You can't.
The place to do this is with Attributes.
Eg
[Name("FooClass")]
class Foo
{
}
If you don't mind deferring to implementations to sensibly implement the Description property, you can simply do
public abstract string ClassDescription {get; }
// ClassDescription is more intention-revealing than Description
And implementing classes would do something like this:
static string classDescription="My Description for this class";
override string ClassDescription { get { return classDescription; } }
Then, your classes are required to follow the contract of having a description, but you leave it to them to do it sensibly. There's no way of specifying an implementation in an object-oriented fashion (except through cruel, fragile hacks).
However, in my mind this Description is class metadata, so I would prefer to use the attribute mechanism as others have described. If you are particularly worried about multiple uses of reflection, create an object which reflects over the attribute that you're concerned with, and store a dictionary between the Type and the Description. That will minimize the reflection (other than run time type inspection, which isn't all that bad). The dictionary can be stored as a member of whatever class that typically needs this information, or, if clients across the domain require it, via a singleton or context object.
If it is static, there is only one instance of the variable, I don't see how inheritance would make sense if we could do what you want to accomplish with static vars in derived classes. Personally I think you are going to far to try to avoid a instance var.
Why not just the classic way?
abstract class AbstractBase
{
protected string _Description = "I am boring abstract default value";
}
class Foo : AbstractBase {
public Foo() {
_Description = "I am foo!";
}
}
Combining static and abstract is somewhat meaningless, yes. The idea behind static is one need not present an instance of the class in order to use the member in question; however with abstract, one expects an instance to be of a derived class that provides a concrete implementation.
I can see why you'd want this sort of combination, but the fact is the only effect would be to deny the implementation use of 'this' or any non-static members. That is, the parent class would dictate a restriction in the implementation of the derived class, even though there's no underlying difference between calling an abstract or 'static abstract' member (as both would need a concrete instance to figure out what implementation to use)
A possible workaround is to define a Singleton of your derived class in your base class with the help of Generics.
import System;
public abstract class AbstractBase<T>
where T : AbstractBase<T>, new()
{
private static T _instance = new T();
public abstract string Description { get; }
public static string GetDescription()
{
return _instance.Description;
}
}
public class DerivedClass : AbstractBase<DerivedClass>
{
public override string Description => "This is the derived Class";
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(DerivedClass.GetDescription());
Console.ReadKey();
}
}
The trick is to tell your AbstractBase<T> some details about how DerivedClass is implemented:
It is newable with where T: new() so it can create a Singleton instance
It derives from itself with where T : AbstractBase<T> so it knows that there will be a implementation of Description
This way _instance contains the Description field which can be called in the static Method GetDescription().
This forces you to overwrite Descriptionin your DerivedClass and allows you to call its value with DerivedClass.GetDescription()
It's not static if it has to be called on an instance.
If you're not calling it on an instance, then there's no polymorphism at play (i.e. ChildA.Description is completely unrelated to ChildB.Description as far as the language is concerned).
You can...
In the abstract class...
protected abstract InWindow WindowInstance { get; set; }
In the derived class...
private static InWindow _instance;
protected override InWindow WindowInstance
{
get => _instance;
set => _instance = value;
}
You could make the "abstract" base method throw an Exception, so then a developer is "warned" if he tries to invoke this method on a child class without overriding.
The downside is that one might extend the class and not use this method. Then refer to other answers provided.

Categories