Create a custom list without default methods - c#

I am creating a list derived from CollectionBase, so that I can use my own methods. This is made in a dll project.
I just wanted to know if it is possible to hide the default methods from CollectionBase, so that only my methods appear when this list is being used.

If you derive from CollectionBase, then no, it's not possible. Your class then is a CollectionBase and so inherits all its methods. The need to hide something that you inherit is a clear hint that you should not use inheritence.
You could use composition instead:
public class MyList
{
private List<int> _privateList = new List<int>();
public void MyMethod1()
{
// Do something
}
public void MyMethod2()
{
// Do something
}
public void Add(int x)
{
_privateList.Add(x);
}
// etc.
}

If its virtual method, you can override and change to whatever behavior you want. If its not a virtual method, you can't hide them.
In any case you can re-declare the method with new (with same signature) and mark it with Obsolete attribute. This will force that compiler generates error if someone wants to use them. In following example calling Child.Method() will generate compiler error. This guarantees that no one can use the parent's method.
public class Parent
{
public void Method()
{
}
}
public class Child : Parent
{
[Obsolete("This method should not be used", true)]
public new void Method()
{
}
}

Related

How to create an Action with generic argument?

example
i have a class
using System;
namespace ConsoleApp1
{
public interface INode<T>
{
T Value { get; }
}
public class A
{
public void Do1(INode<string> node) { }
public void Do2<T>(INode<T> node) { }
}
public class Programm
{
public static void Main(string[] args)
{
A a = new A();
//now I want to pass this method to an another class as arguments
//it's OK here
var processor1 = new Proccessor(a.Do1);
//no idea how to achieve this without making class Proccessor generic type
var processor2 = new Proccessor(a.Do2);
}
}
public class Proccessor
{
//it's OK here
public Proccessor(Action<INode<string>> do1Action)
{
}
//no idea how to achieve this without making class Proccessor generic type
public Proccessor(Action<T><INode<T>> do2Action)
{
}
}
}
It looks like you're trying to pass an Action<T> to a method such that the method can then choose which T to invoke it for. That's simply not possible.
The easiest way around this is avoiding generics entirely, by making all BaseNodeViewModel<T, U> derive from a common non-generic BaseNodeViewModel type. Your OnNodeExpanded then looks like
private void OnNodeExpanded(BaseNodeViewModel node) { ... }
and it may cast node to the concrete type as needed in its implementation.
A more advanced way around this is creating a custom interface type
internal interface INodeExpanded {
void OnNodeExpanded<TNode>(BaseNodeViewModel<TNode, FolderTreeViewModel> node);
}
You can then manually create a class which implements this interface, and pass that to A instead of a delegate.
The answer to this question depends on what exactly you expect to be able to do with do2Action inside the class.
Do you to say "I want to accept and store an action that will be able to work with any INode"? Assuming that's the case, make INode covariant, and demand an Action<INode<object>>. Like so:
public interface INode<out T>
{
T Value { get; }
}
Then...
public Proccessor(Action<INode<object>> do2Action)
{
}
Now you can do:
var processor2 = new Proccessor((Action<INode<object>>)a.Do2(x));
The cast is required to disambiguate from the string overload, but if you remove the overloads and instead use distinctly named static methods to construct, you will find that this is type safe.
Note that an immense responsibility has now been pushed to a.Do2, it must be able to work with any INode whatsoever, without restriction.
You can't have a generic constructor for a non-generic class. You have at least 3 options (Asad's answer is also very good if your intentions are what he specified in his answer):
don't use generics. see hvd's answer.
make the class generic.
don't use T in the constructor, but in another method. You can have a static method that will create and return an instance of the class for you, there you can use the generic action:
public class Proccessor
{
//it's OK here
public Proccessor(Action<INode<string>> do1Action)
{
}
private Proccessor()
{
// a private constructor for the CreateProcessor static method
}
public static Proccessor CreateProccessor<T>(Action<INode<T>> do2Action)
{
var proccessor = new Proccessor();
// invoke action here
}
}

Possible to determine if a method is called by a derived class or directly as itself? C#

Is there any direct way to determine if a method in a base class (not an abstract) is called by a derived class or explicitly from somewhere that has created an instance of base class?
The simplest method is to use reflection:
public virtual void MyBaseClassMethod()
{
var currType = this.GetType();
if (currType == typeof(MyBaseClass))
{
// base class instantiated directly.
}
}
If you can change the code you could do something like this...
public MyDerivedClass : MyBaseClass
{
public override void MyPublicMethod()
{
MyPrivateMethod(false);
}
}
public MyBaseClass
{
public virtual void MyPublicMethod()
{
MyInternalMethod(true);
}
protected void MyInternalMethod(bool isInternal)
{
// If you're planning to use isInternal to change the logic based
// on whether this code has been invoked in the base or subclass
// you would be infinitely better off overriding that code in the
// subclass. Or better still don't use generalization at all and
// use an injection framework and create several implementations
// of an interface.
}
}

Why do we use virtual and override?

Why do we use override and virtual if it gives the same effect when we dont use override and virtual?
example 1:
class BaseClass
{
public virtual string call()
{
return "A";
}
}
class DerivedClass : BaseClass
{
public override string call()
{
return "B";
}
}
output : B
Example 2:
class BaseClass
{
public string call()
{
return "A";
}
}
class DerivedClass : BaseClass
{
public string call()
{
return "B";
}
}
and the output is still the same:
output : B
to run the test:
class Program
{
static void Main(string[] args)
{
DerivedClass dc = new DerivedClass();
Console.WriteLine(dc.call());
Console.ReadKey();
}
}
Does the compiler add virtual and override automatically at compile time?
I would be pleased if someone would explain to me the reason for using virtual and override.
(note, I'm quietly ignoring the compile errors)
Now do:
BaseClass obj = new DerivedClass();
Console.WriteLine(obj.call());
Without virtual, this will print A, when actually a DerivedClass should be writing B. This is because it has simply called the BaseClass implementation (since obj is typed as BaseClass, and no polymorphism is defined).
Virtual and override are a base mechanism of inheritance in object oriented programming.
This is perhaps the most important thing to understand when you use classes in a language like C# or Java.
http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)
Inheritance allow you to reuse code adding new fields, properties and methods or replacing methods and properties of previously defined classes.
Virtual and Override allow you to replace the content of a method, and when i say replace, i say replace.
I would propose you a nice example.
public class MyClassEnglish
{
public virtual string SomethingToSay()
{
return "Hello!";
}
public void WriteToConsole()
{
Console.WriteLine(this.SomethingToSay());
}
}
public class MyClassItalian :
MyClassEnglish
{
public override string SomethingToSay()
{
return "Ciao!";
}
}
int main()
{
MyClassItalian it = new MyClassItalian();
it.WriteToConsole();
}
If you omit virtual and override, MyClassItalian will print out "Hello!" and not "Ciao!".
In your example you show a Shadowing technique, but the compiler should give you a warning.
You shoul add the "new" keyword if you want to hide a method in a base class.
Hiding a method is not overriding! Is just hiding.
One possible use that comes into my mind is that it can be used when you need some kind of optimization for example.
public abstract class MySpecialListBase
{
public int Count()
{
return this.GetCount();
}
protected abstract int GetCount();
}
public sealed class MySpecialArrayList : MySpecialListBase
{
int count;
public new int Count()
{
return this.count;
}
protected override int GetCount()
{
return this.count;
}
}
Now...
You can use MySpecialListBase in all your code, and when you call the Count() it will call the virtual method GetCount().
But if you use just MySpecialArrayList it will call the optimized Count() that is not virtual and that just return a field, increasing performances.
// This works with all kind of lists, but since it is a more general purpose method it will call the virtual method.
public void MyMethod(MySpecialListBase list)
{
Console.WriteLine(list.Count());
}
// This works only with MySpecialArrayList, and will use the optimized method.
public void MyMethod(MySpecialArrayList list)
{
Console.WriteLine(list.Count());
}
Best example I can think of where this is useful is when you create your own object(class) and you have to add a list of that object to a combobox.
When you add your object to the combobox you want to be able to control what text is displayed for each item. Object.toString is a virtual method. http://msdn.microsoft.com/en-us/library/system.object.tostring.aspx and because of this you can override that method and set .toString to display the correct information about your object by overriding it.
public MyClass()
{
private int ID;
public override string ToString()
{
return "My Item:" + ID;
}
}
Method Overriding:
Where you define or implement a virtual method in a parent class and then replace it in a descendant class.
When you decide to declare a method as virtual, you are giving permission to derived classes to extend and override the method with their own implementation. You can have the extended method call the parent method's code too.
In most OO languages you can also choose to hide a parent method. When you introduce a new implementation of the same named method with the same signature without overriding, you are hiding the parent method.
C# Overriding
In C#, you specify a virtual method with the virtual keyword in a parent class and extend (or replace) it in a descendant class using the override keyword.
Use the base keyword in the descendant method to execute the code in the parent method, i.e. base.SomeMethod().
Syntax Example:
class Robot
{
public virtual void Speak()
{
}
}
class Cyborg:Robot
{
public override void Speak()
{
}
}
Override Details
You cannot override a regular non-virtual method, nor a static method.
The first version of the parent method must be virtual or abstract.
You can override any parent method marked virtual, abstract, or override (already overridden).
The methods must have the same signature.
The methods must have the same visibility (the same access level).
Use the base keyword to refer to the parent class as in base.SomeMethod().
C# Override Example
The following code snippet demonstrates using virtual and override to override a parent method in a descendant class.
using System;
class Dog
{
public virtual void Bark()
{
Console.WriteLine("RUFF!");
}
}
class GermanShepard:Dog
{
public override void Bark()
{
Console.WriteLine("Rrrrooouuff!!");
}
}
class Chiuaua:Dog
{
public override void Bark()
{
Console.WriteLine("ruff");
}
}
class InclusionExample
{
public static void Main()
{
Dog MyDog=new Dog();
MyDog=new GermanShepard();
MyDog.Bark(); // prints Rrrrooouuff!!
MyDog=new Chiuaua();
MyDog.Bark(); // prints ruff;
}
}
Hiding a Method with New
Use the new keyword to introduce a new implementation of a parent method (this hides the parent method). You can hide a method without using new but you will get a compiler warning. Using new will suppress the warning.
The new and override modifiers have different meanings. The new modifier creates a new member with the same name, signature, and visibility and hides the original member. The override modifier extends the implementation for an inherited member and allows you to implement inheritance-based polymorphism.
Avoid Introducing New Members: Sometimes there are clear reasons to introduce a new method with the same name, signature, and visibility of a parent method. In those clear cases, introducing a new member is a powerful feature. However, if you do not have a clear reason, then avoid introducing a new version of a method by naming the new method something unique and appropriate.
class Robot : System.Object
{
public void Speak()
{
MessageBox.Show("Robot says hi");
}
}
class Cyborg : Robot
{
new public void Speak()
{
MessageBox.Show("hi");
}
}
Calling the Base Class Version
A common task In OO is to extend a method by first executing the parent method code and then adding code. Use the base keyword to refer to the parent class as in base.SomeMethod().
class Robot : System.Object
{
public virtual void Speak()
{
MessageBox.Show("Robot says hi");
}
}
class Cyborg : Robot
{
public override void Speak()
{
base.Speak();
MessageBox.Show("hi");
}
}

Inheritence in C# question - is overriding internal methods possible?

Is it possible to override an internal method's behavior?
using System;
class TestClass
{
public string Name { get { return this.ProtectedMethod(); } }
protected string ProtectedMethod()
{
return InternalMethod();
}
string InternalMethod()
{
return "TestClass::InternalMethod()";
}
}
class OverrideClassProgram : TestClass
{ // try to override the internal method ? (doesn't work)
string InternalMethod()
{
return "OverrideClassProgram::InternalMethod()";
}
static int Main(string[] args)
{
// TestClass::InternalMethod()
Console.WriteLine(new TestClass().Name);
// TestClass::InternalMethod() ?? are we just screwed?
Console.WriteLine(new OverrideClassProgram().Name);
return (int)Console.ReadKey().Key;
}
}
I think you've got something confused here. There is an actual keyword "internal", is this what you want?
internal string InternalMethod()
{
return "TestClass::InternalMethod()";
}
But I think what you're really looking for is the "virtual" keyword. This allows you to do an override:
Parent Class
protected virtual string InternalMethod()
{
return "TestClass::InternalMethod()";
}
Child Class
protected override string InternalMethod()
{
return "TestProgram::InternalMethod()";
}
Using the "new" keyword is valid, but it completely reimplements the method. I.e. it breaks polymorphism.
Edit:
Here's a link.
In Java everything is virtual unless it is static/final. In C# you have to explicitly declare an instance method as virtual and then that method cannot be private. This article explains why.
By default all members of a class are private, so if you do not provide an access modifier (other than private of course) the InternalMethod() method in your example is private and cannot be virtual and thus cannot be overridden.
You must change it's access modifier and mark it as virtual and in the child class you must override it for the code to work the way you want it too.
This may not answer your question, but just to add a cent.
Internal denotes that types or members are accessible only within files in the same assembly. They are public to the assembly but having access slightly less than the public in actual.
MSDN Access Modifiers,
A common use of internal access is in
component-based development because it
enables a group of components to
cooperate in a private manner without
being exposed to the rest of the
application code. For example, a
framework for building graphical user
interfaces could provide Control and
Form classes that cooperate using
members with internal access. Since
these members are internal, they are
not exposed to code that is using the
framework
Try using the override keyword ... the new keyword is to call a class constuctor
Sure, it's possible, but in order to override a method, the method needs to be virtual or abstract, same as any other visibility.
class Base
{
internal virtual void Foo()
{
Console.WriteLine("Foo from Base");
}
}
class Derived : Base
{
internal override void Foo()
{
Console.WriteLine("Foo from Derived");
}
}
When you use the new keyword, it's called method hiding, which is not the same thing. If I write this:
class Base
{
internal void Foo()
{
Console.WriteLine("Foo from Base");
}
}
class Derived : Base
{
internal new void Foo()
{
Console.WriteLine("Foo from Derived");
}
}
static void Main()
{
Base b = new Derived();
b.Foo();
}
Then it will execute the Base Foo method, not Derived. In other words it will print Foo from Base. In the first case, it would still have executed the Derived method and printed Foo from Derived.

Why can't I declare C# methods virtual and static?

I have a helper class that is just a bunch of static methods and would like to subclass the helper class. Some behavior is unique depending on the subclass so I would like to call a virtual method from the base class, but since all the methods are static I can't create a plain virtual method (need object reference in order to access virtual method).
Is there any way around this? I guess I could use a singleton.. HelperClass.Instance.HelperMethod() isn't so much worse than HelperClass.HelperMethod(). Brownie points for anyone that can point out some languages that support virtual static methods.
Edit: OK yeah I'm crazy. Google search results had me thinking I wasn't for a bit there.
I don't think you are crazy. You just want to use what is impossible currently in .NET.
Your request for virtual static method would have so much sense if we are talking about generics.
For example my future request for CLR designers is to allow me to write intereface like this:
public interface ISumable<T>
{
static T Add(T left, T right);
}
and use it like this:
public T Aggregate<T>(T left, T right) where T : ISumable<T>
{
return T.Add(left, right);
}
But it's impossible right now, so I'm doing it like this:
public static class Static<T> where T : new()
{
public static T Value = new T();
}
public interface ISumable<T>
{
T Add(T left, T right);
}
public T Aggregate<T>(T left, T right) where T : ISumable<T>, new()
{
return Static<T>.Value.Add(left, right);
}
Virtual static methods don't make sense. If I call HelperClass.HelperMethod();, why would I expect some random subclass' method to be called? The solution really breaks down when you have 2 subclasses of HelperClass - which one would you use?
If you want to have overrideable static-type methods you should probably go with:
A singleton, if you want the same subclass to be used globally.
A tradition class hierarchy, with a factory or dependency injection, if you want different behavior in different parts of your application.
Choose whichever solution makes more sense in your situation.
You can achieve the same effect by just having a regular static method and then shadow it with the new keyword
public class Base
{
//Other stuff
public static void DoSomething()
{
Console.WriteLine("Base");
}
}
public class SomeClass : Base
{
public new static void DoSomething()
{
Console.WriteLine("SomeClass");
}
}
public class SomeOtherClass : Base
{
}
Then you can call the methods like so
Base.DoSomething(); //Base
SomeClass.DoSomething(); //SomeClass
SomeOtherClass.DoSomething(); //Base
Indeed, this can be done in Delphi. An example:
type
TForm1 = class(TForm)
procedure FormShow(Sender: TObject);
end;
TTestClass = class
public
class procedure TestMethod(); virtual;
end;
TTestDerivedClass = class(TTestClass)
public
class procedure TestMethod(); override;
end;
TTestMetaClass = class of TTestClass;
var
Form1: TForm1;
implementation
{$R *.dfm}
class procedure TTestClass.TestMethod();
begin
Application.MessageBox('base', 'Message');
end;
class procedure TTestDerivedClass.TestMethod();
begin
Application.MessageBox('descendant', 'Message');
end;
procedure TForm1.FormShow(Sender: TObject);
var
sample: TTestMetaClass;
begin
sample := TTestClass;
sample.TestMethod;
sample := TTestDerivedClass;
sample.TestMethod;
end;
Quite interesting. I no longer use Delphi, but I recall being able to very easily create different types of controls on a custom designer canvas using the metaclass feature: the control class, eg. TButton, TTextBox etc. was a parameter, and I could call the appropriate constructor using the actual metaclass argument.
Kind of the poor man's factory pattern :)
I come from Delphi and this is a feature among many that I sorely miss in c#. Delphi would allow you to create typed type references and you could pass the type of a derived class wherever the type of a parent class was needed. This treatment of types as objects had powerful utility. In particular allowing run time determination of meta data. I am horribly mixing syntax here but in c# it would look something like:
class Root {
public static virtual string TestMethod() {return "Root"; }
}
TRootClass = class of TRoot; // Here is the typed type declaration
class Derived : Root {
public static overide string TestMethod(){ return "derived"; }
}
class Test {
public static string Run(){
TRootClass rc;
rc = Root;
Test(rc);
rc = Derived();
Test(rc);
}
public static Test(TRootClass AClass){
string str = AClass.TestMethod();
Console.WriteLine(str);
}
}
would produce:
Root
derived
You are not crazy. What you are referring to is called Late Static Binding; it's been recently added to PHP. There's a great thread that describes it - here: When would you need to use late static binding?
a static method exists outside of an instance of a class. It cannot use any non-static data.
a virtual method will be "overwritten" by an overloaded function depending of the type of an instance.
so you have a clear contradiction between static and virtual.
This is not a problem of support, It is a concept.
Update: I was proven wrong here(see comments):
So I doubt you will find any OOP-Language which will support virtual
static methods.
There is a way to force an inheritance of "abstract static" methods from an abstract generic class. See as follow :
public abstract class Mother<T> where T : Mother<T>, new()
{
public abstract void DoSomething();
public static void Do()
{
(new T()).DoSomething();
}
}
public class ChildA : Mother<ChildA>
{
public override void DoSomething() { /* Your Code */ }
}
public class ChildB : Mother<ChildB>
{
public override void DoSomething() { /* Your Code */ }
}
Example (using the previous Mother):
public class ChildA : Mother<ChildA>
{
public override void DoSomething() { Console.WriteLine("42"); }
}
public class ChildB : Mother<ChildB>
{
public override void DoSomething() { Console.WriteLine("12"); }
}
public class Program
{
static void Main()
{
ChildA.Do(); //42
ChildB.Do(); //12
Console.ReadKey();
}
}
It's not that great since you can inherit from only one abstract class and it will ask you to be lenient with your new() implementation.
More, I think it will be costly memory-wise depending on the size of your inherited classes.
In case you have memory issue, you would have to set every properties/variables after your new in a public method which is an awful way to have default values.
I heard that Delphi suports something like this. It seems it does it by making classes object instances of a metaclass.
I've not seen it work, so I'm not sure that it works, or what's the point for that.
P.S. Please correct me if I'm wrong, since it's not my domain.
Because a virtual method uses the defined type of the instantiated object to determine which implementation to execute, (as opposed to the declared type of the reference variable)
... and static, of course, is all about not caring if there's even an instantiated instance of the class at all...
So these are incompatible.
Bottom line, is if you want to change behavior based on which subclass an instance is, then the methods should have been virtual methods on the base class, not static methods.
But, as you already have these static methods, and now need to override them, you can solve your problem by this:
Add virtual instance methods to the base class that simply delegate to the static methods, and then override those virtual instance wrapper methods (not the static ones) in each derived subclass, as appropriate...
It is actually possible to combine virtual and static for a method or a member by using the keyword new instead of virtual.
Here is an example:
class Car
{
public static int TyreCount = 4;
public virtual int GetTyreCount() { return TyreCount; }
}
class Tricar : Car
{
public static new int TyreCount = 3;
public override int GetTyreCount() { return TyreCount; }
}
...
Car[] cc = new Car[] { new Tricar(), new Car() };
int t0 = cc[0].GetTyreCount(); // t0 == 3
int t1 = cc[1].GetTyreCount(); // t1 == 4
Obviously the TyreCount value could have been set in the overridden GetTyreCount method, but this avoids duplicating the value. It is possible to get the value both from the class and the class instance.
Now can someone find a really intelligent usage of that feature?
Mart got it right with the 'new' keyword.
I actually got here because I needed this type of functionality and Mart's solution works fine. In fact I took it one better and made my base class method abstract to force the programmer to supply this field.
My scenario was as follows:
I have a base class HouseDeed. Each House type is derived from HouseDeed must have a price.
Here is the partial base HouseDeed class:
public abstract class HouseDeed : Item
{
public static int m_price = 0;
public abstract int Price { get; }
/* more impl here */
}
Now lets look at two derived house types:
public class FieldStoneHouseDeed : HouseDeed
{
public static new int m_price = 43800;
public override int Price { get { return m_price; } }
/* more impl here */
}
and...
public class SmallTowerDeed : HouseDeed
{
public static new int m_price = 88500;
public override int Price { get { return m_price; } }
/* more impl here */
}
As you can see I can access the price of the house via type SmallTowerDeed.m_price, and the instance new SmallTowerDeed().Price
And being abstract, this mechanism nags the programmer into supplying a price for each new derived house type.
Someone pointed how 'static virtual' and 'virtual' are conceptually at odds with one another. I disagree. In this example, the static methods do not need access to the instance data, and so the requirements that (1) the price be available via the TYPE alone, and that (2) a price be supplied are met.
An override method provides a new implementation of a member that is inherited from a base class. The method that is overridden by an override declaration is known as the overridden base method. The overridden base method must have the same signature as the override method.
You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, or override.
An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.
You cannot use the new, static, or virtual modifiers to modify an override method.
An overriding property declaration must specify exactly the same access modifier, type, and name as the inherited property, and the overridden property must be virtual, abstract, or override.
You can use the new keyword
namespace AspDotNetStorefront
{
// This Class is need to override StudioOnlineCommonHelper Methods in a branch
public class StudioOnlineCommonHelper : StudioOnlineCore.StudioOnlineCommonHelper
{
//
public static new void DoBusinessRulesChecks(Page page)
{
StudioOnlineCore.StudioOnlineCommonHelper.DoBusinessRulesChecks(page);
}
}
}
It is possible to simulate the functionality by using the new keyword in the derived class and throwing the NotSupportedException() in the base.
public class BaseClass{
public static string GetString(){
throw new NotSupportedException(); // This is not possible
}
}
public class DerivedClassA : BaseClass {
public static new string GetString(){
return "This is derived class A";
}
}
public class DerivedClassB : BaseClass {
public static new string GetString(){
return "This is derived class B";
}
}
static public void Main(String[] args)
{
Console.WriteLine(DerivedClassA.GetString()); // Prints "This is derived class A"
Console.WriteLine(DerivedClassB.GetString()); // Prints "This is derived class B"
Console.WriteLine(BaseClass.GetString()); // Throws NotSupportedException
}
Due to the fact that it is not possible to detect this condition at compile time and that IntelliSense won't suggest that such function should be implemented in the derived class, this is a potential headache.
One comment also suggested to use NotImplemetedException(). Microsoft's documentation indicates that neither of these exceptions should be handled so any of them should work.
The differences between NotSupportedException and NotImplemetedException are commented in this blog.
You will be able to soon, in C# 11!
From Tutorial: Explore C# 11 feature - static virtual members in interfaces:
C# 11 and .NET 7 include static virtual members in interfaces. This feature enables you to define interfaces that include overloaded operators or other static members.

Categories

Resources