Can any one explain in the detail(with example) the different purpose of the "new" in C#.
You have:
new operator:
Used to create objects and invoke
constructors
new modifier
When used as a modifier, the new
keyword explicitly hides a member
inherited from a base class
new constraint
The new constraint specifies that any
type argument in a generic class
declaration must have a public
parameterless constructor
Object instantiation
In anonymous types
To signal that a member of the base class is being hidden.
As a constraint
About 3 (from MSDN):
public class BaseC
{
public int x;
public void Invoke() { }
}
public class DerivedC : BaseC
{
new public void Invoke() { }
}
The keyowrd is not necessary but should be used to make it clear that the base-class constructor is being hidden.
Related
I have a set of classes that inherit from a base...
public abstract class BaseClass
{
public BaseClass()
{
// ...
}
}
public abstract class BaseMessageClass : BaseClass
{
// ...
}
public SpecificMessageClass : BaseMessageClass
{
// ...
}
Instantiating an object like this works:
SpecificMessageClass myMessage = new SpecificMessageClass();
However, I need to change all constructors to have an optional string parameter, like this:
public abstract class BaseClass
{
public BaseClass(string optParam="whatever")
{
// ...
}
}
Now, when I try and instantiate the object with the optional argument:
SpecificMessageClass myMessage = new SpecificMessageClass("coolstring");
I get the error:
'SpecificMessageClass' does not contain a constructor that takes 1 arguments"
Is there ANY way to do this without explicitly declaring the constructors in each level of inherited class?
No.
But given that you want to inherit, I'm guessing you want the same logic to apply at all levels on some inherited field or property. If so, the closest you can get is to add a factory method like a Create<T>(string optParam="whatever") on the base class like the following:
public class BaseClass
{
public static T Create<T>(string optParam="whatever") where T : BaseClass
{
var t = new T(); //which invokes the paramterless constructor
((BaseClass)t).SomePropertyOrFieldInheritedFromTheBaseClass = optParam; //and then modifies the object however your BaseClass constructor was going to.
return t;
}
}
That would allow all implementers of the class to implement the BaseClass and get the same effect as having the optional parameter constructor.
By the way, I didn't test the above code, so you might need to tweak it slightly. But hopefully it gives the idea.
I think that's probably the closest you can get.
Constructors are special methods. If your class specifies no constructors, it will have a no-args constructor that inherits from the parent's no-args constructor. As soon as you specify a single constructor, you do not automatically get any of the parent's constructors for free. You must declare each different constructor you need.
Say Class A is the base class and then you have class B subclass of A (class B : A). Then you have class C : B.
Question is if you have a method in class A, can class C use that method?
Yes, you can, if it is declared public or protected. but not private.
Thanks to #DavidL.. I forgot to mention the special case of internal.
From C# Manual that comes with Visual Studio (2012 edition here)::
• Inheritance is transitive. If C is derived from B, and B is derived
from A, then C inherits the members declared in B as well as the
members declared in A. • A derived class extends its direct base
class. A derived class can add new members to those it inherits, but
it cannot remove the definition of an inherited member. • Instance
constructors, destructors, and static constructors are not inherited,
but all other members are, regardless of their declared accessibility
(§3.5). However, depending on their declared accessibility, inherited
members might not be accessible in a derived class. • A derived class
can hide (§3.7.1.2) inherited members by declaring new members with
the same name or signature. Note however that hiding an inherited
member does not remove that member—it merely makes that member
inaccessible directly through the derived class. • An instance of a
class contains a set of all instance fields declared in the class and
its base classes, and an implicit conversion (§6.1.6) exists from a
derived class type to any of its base class types. Thus, a reference
to an instance of some derived class can be treated as a reference to
an instance of any of its base classes. • A class can declare virtual
methods, properties, and indexers, and derived classes can override
the implementation of these function members. This enables classes to
exhibit polymorphic behavior wherein the actions performed by a
function member invocation varies depending on the run-time type of
the instance through which that function member is invoked.
Also this is a new hiding feature, if I am right, in C# 5.0:
A nested type may hide (§3.7.1) a base member. The new modifier is permitted on nested type declarations so that hiding can be expressed explicitly. The example
using System;
class Base
{
public static void M() {
Console.WriteLine("Base.M");
}
}
class Derived: Base
{
new public class M
{
public static void F() {
Console.WriteLine("Derived.M.F");
}
}
}
class Test
{
static void Main() {
Derived.M.F();
}
}
shows a nested class M that hides the method M defined in Base.
It depends.
When the method in class A is private: no
When the method in class A is protected: yes
When the method in class A is public: yes
When the method in class A is public or protected and virtual, class C can override that method.
Yes, when you inherit from a class you get all of it's methods, including all those it inherited from others.
public class A
{
public int Id { get; set; }
protected int protectedId { get; set; }
private int privateId;
}
public class B : A
{
}
public class C : B
{
public C()
{
int temp = Id; // works
int temp1 = protectedId; // works
int temp2 = privateId; // does NOT work
}
}
and in some other class;
public void SomeMethod()
{
C c = new C();
int i = c.Id; // works
int j = c.protectedId; // does NOT work
int k = c.privateId; // does NOT work
}
I've created a generic class that needs to instantiate its implementation type, so the implementation type has to have an accessible parameter less constructor. Looks like the new() restriction could do the job but its enforcing the implementation type to have a public constructor when I have it internal (but accessible as both are on the same assembly).
Is there a reason to force it to be public rather than "accessible"?
Is there a way to do what I need?
Thanks in advance.
EDIT: The reason to do this is that I have a class X that must be used through a Singleton. The Singleton class is a generic class and I want to make the class X constructor internal to avoid external users accessing the object in a wrong way (calling the constructor).
This is disallowed by the C# language as outlined in section 4.4.3 of the specification Bound and Unbound Types.
If the constraint is the constructor constraint new(), the type A must not be abstract and must have a public parameterless constructor. This is satisfied if one of the following is true.
A is a value type, since all value types have a public default constructor
A is a type parameter having the cosntructor constraint
A is a type parameter having the value type constraint
A is a class that is not abstract and contains an explicitly declared public constuctor with no parameters
A is not abstract and has a default constructor.
A compiler error if any one of these conditions are not met. If you find yourself having types that are public but only with internal constructors, then most likely they should actually be internal types with public constructors.
I would recommend changing your types accessor to internal and its constructor's to public, and make it parameterless. Your public parameterless constructor could then call through to a non-parameterless private or internal constructor to do any additional initialization work.
internal class C<T> where : T new()
{
public C() : this(new T()) {
}
private C(T t) {
// Do additional initialization
}
}
Mind you that pattern is limited, but there's nothing stopping you from using a private method instead.
internal class C<T> where T : new() {
public C() {
T t = new T();
InitializeClass(t);
}
private void InitializeClass(T t) {
throw new NotImplementedException();
}
}
As per your update, here's a small example of a public singleton patter.
public class Singleton<T> where T : new()
{
public static Singleton<T> Current {
get;
private set;
}
internal Singleton() : this(new T()) {
}
private Singleton(T t) {
Current = this;
// Do whatever you need to with T
}
public String Name {
get;
set;
}
}
Usage
// Somewhere in your internal assembly
Singleton<String> singleton = new Singleton<String>();
// In an external assembly
Singleton.Current.Name = "SoMoS";
You don't even need to use constructors in that fashion either, you can just as easily do something simple.
public class Singleton<T> where T : new()
{
public static Singleton<T> Current {
get;
private set;
}
internal Singleton() {
T t = new T();
// Do stuff with T
}
public String Name {
get;
set;
}
}
Generics may not be the way to go if you can't design it to fit your requirements. Generics can only do so much and don't solve every problem. There are things like Factory Pattern, Injection, etc..
Is there a reason to force it to be public rather than "accessible"?
Term accessible is very context sensitive, generics are not, by architecture.
In your specific case internal could be accessible, but generics are made for generic solutions.
Is there a way to do what I need?
Based on first point, no, it's not possible, nor that I'm aware of.
Generics are for generic solution, therefore if you use the "new" constraint, your solution have to work with every class which implements a public ctor.
If you want to implement a generic solution for a specific kind of classes you can define an abstract base class which implements a such internal constructor. Implement a generic solution for this abstract base class and use
*
where T : MyBaseClassWithInternalCtor
*
as constraint.
Here is what I'm trying to do, not even sure if possible..
I'm creating BaseViewModel<T> and I want it to accept types inherited from Entity
Consider this code:
public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
{
public T MyEntity;
public SomeMethod()
{
MyEntity.SomeEntityProperty = SomeValue;
}
}
So, I want to say that my T inherited from Entity and therefore I KNOW that it will have SomeEntityProperty.
Is this possible?
Salvatore's answer is totally correct, I just wanted to describe the concept a little better.
What you need is a "generic type constraint"; to specify that the type used as T must conform to certain behaviors (such as being derived from an object or interface more derived than Object), thus increasing what you are allowed to do with that object without further casting (which is generally to be avoided in generics).
As Salvatore's answer shows, GTCs are defined using the "where" keyword:
public abstract class BaseViewModel<T> :
NotificationObject,
INavigationAware
where T : Entity;
{
...
This GTC basically states that any T must derive (however remotely) from Entity. This allows you to treat T as if it were an Entity (except for instantiation of new Ts; that requires an additional GTC), regardless of how more or less derived the actual generic parameter type is from Entity. You can call any method that appears on Entity, and get/set any field or property.
You can also specify that:
The type must be a class (where T:class), or alternately must be a ValueType (where T:struct). This either permits or prevents comparison and assignment of a T instance to null, which also allows or prevents use of the null-coalescing operator ??.
The type must have a parameterless constructor (where T:new()). This allows instantiations of Ts using the new keyword, by ensuring at compile-time that all types used as Ts have a constructor that takes no parameters.
public abstract class BaseViewModel<T> :
NotificationObject,
INavigationAware
where T : Entity
{
public T MyEntity;
public SomeMethod()
{
MyEntity.SomeEntityProperty = SomeValue;
}
}
Just use the where keyword:
public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
where T:Entity
{
...
Try using the where constraint:
public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
where T : Entity
{
public T MyEntity;
public SomeMethod()
{
MyEntity.SomeEntityProperty = SomeValue;
}
}
What is the purpose of base() in the following code?
class mytextbox : TextBox
{
public mytextbox() : base()
{
this.Text = "stack";
}
}
Why At design time messages are displayed ؟
my code :
class Class1:TextBox
{
public Class1()
{
this.Resize += new EventHandler(Class1_Resize);
}
void Class1_Resize(object sender, EventArgs e)
{
MessageBox.Show("Resize");
}
}
base() in your code is a call to the parameterless constructor of the base-class ofmyTextBox, which happens to beTextBox. Note that this base constructor will execute before the execution of the body of the constructor in the derived class.
Every class's constructor must eventually call one of its base class's constructors, either directly or through chained constructors in the same class. Consequently, there is always an implicit / explicit base(...) or explicit this(...) call on every constructor declaration. If it is omitted, there an implicit call to base(), i.e. the parameterless constructor of the base class (this means that the call tobase()in your example is redundant). Whether such a declaration compiles or not depends on whether there exists such an accessible constructor in the base class.
EDIT:
Two trivial points:
The root of the class-hierarchy does not have a base class, so this rule does not apply to System.Object's only constructor.
The first sentence should read: "every non-System.Object class's constructor that completes successfully must eventually call one of its base class's constructors." Here is a 'turtles all the way down' example where the base class's contructor is never called: instantiating an object of such a class will obviously overflow the execution-stack.
// Contains implicit public parameterless constructor
public class Base { }
// Does not contain a constructor with either an explicit or implicit call to base()
public class Derived : Base
{
public Derived(int a)
: this() { }
public Derived()
: this(42) { }
static void Main()
{
new Derived(); //StackOverflowException
}
}
No idea, it is unnecessary. A constructor always calls the base class constructor automatically without you having to write it explicitly. But that's what it means. You'd have to write it if you don't want to call the parameterless constructor but one that takes an argument.