C# Function Inheritance--Use Child Class Vars with Base Class Function - windows

Good day, I have a fairly simple question to experienced C# programmers. Basically, I would like to have an abstract base class that contains a function that relies on the values of child classes. I have tried code similar to the following, but the compiler complains that SomeVariable is null when SomeFunction() attempts to use it.
Base class:
public abstract class BaseClass
{
protected virtual SomeType SomeVariable;
public BaseClass()
{
this.SomeFunction();
}
protected void SomeFunction()
{
//DO SOMETHING WITH SomeVariable
}
}
A child class:
public class ChildClass:BaseClass
{
protected override SomeType SomeVariable=SomeValue;
}
Now I would expect that when I do:
ChildClass CC=new ChildClass();
A new instance of ChildClass should be made and CC would run its inherited SomeFunction using SomeValue. However, this is not what happens. The compiler complains that SomeVariable is null in BaseClass. Is what I want to do even possible in C#? I have used other managed languages that allow me to do such things, so I certain I am just making a simple mistake here.
Any help is greatly appreciated, thank you.

You got it almost right, but you need to use properties instead of variables:
public abstract class BaseClass {
protected SomeType SomeProperty {get; set}
public BaseClass() {
// You cannot call this.SomeFunction() here: the property is not initialized yet
}
protected void SomeFunction() {
//DO SOMETHING WITH SomeProperty
}
}
public class ChildClass:BaseClass {
public ChildClass() {
SomeProperty=SomeValue;
}
}
You cannot use FomeFunction in the constructor because SomeProperty has not been initialized by the derived class. Outside of constructor it's fine, though. In general, accessing virtual members in the constructor should be considered suspicious.
If you must pass values from derived classes to base class constructor, it's best to do it explicitly through parameters of a protected constructor.

Related

Unity C# Error: 'Sprite' does not contain a constructor that takes 0 arguments

I've been working on an item system for my game in Unity. I am still pretty new to coding, but I am giving it my best effort.
My Item system Works by accessing interfaces with the data I need. While trying to assign my sprite from the interface to a private variable, I get the error "'Sprite' does not contain a constructor that takes 0 arguments." I have looked all over for solutions, and haven't found any fixes that have worked for me so far.
The Class I created to access the interface looks like this:
public class ISType : IISType {
[SerializeField] string _name;
[SerializeField] Sprite _icon;
ISType()
{
_name = "Type";
_icon = new Sprite(); }
public string Name
{
get
{ return _name; }
set
{ _name = value }
}
public Sprite Icon {
get
{ return _icon; }
set
{ _icon = value; }
}
}
If anyone can tell what is going on I would really appreciate the help! :)
It looks like Sprite does not contain a public constructor accepting zero arguments.
A class with no constructors defined will have a parameterless constructor.
public class MyClass { }
MyClass x= new MyClass(); // this is valid
However if it has any other constructors defined, this parameterless 'default' constructor is no longer 'a given'.
Difference between default constructor and paramterless constructor?
Answer by Nicole Calinoiu
The "default" constructor is added by the C# compiler if your class does not contain an explicit instance constructor. It is a public, parameterless constructor.
https://stackoverflow.com/a/10498709/5569485
public class MyClass {
public MyClass(string foo)
{
}
}
MyClass x= new MyClass(); // this is invalid
The class would have to manually define a parameterless constructor.
public class MyClass {
// parameterless constructor
public MyClass()
{
}
public MyClass(string foo)
{
}
}
MyClass x= new MyClass(); // this is valid again!
Sometimes no constructors are provided publicly, and a class instead provides static methods to instantiate the object.
public class MyClass
{
private MyClass()
{
}
public static MyClass Create()
{
return new MyClass();
}
}
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/private-constructors
A private constructor is a special instance constructor. It is generally used in classes that contain static members only. If a class has one or more private constructors and no public constructors, other classes (except nested classes) cannot create instances of this class.
Without knowing more about the Sprite class, my guess is that there is a static method for creating instances of the Sprite
something like
Sprite sprite = Sprite.Create(...);
The answer is in the error. There is no constructor that takes 0 parameters for Sprite. Without seeing the code I'm guessing you made a custom constructor with parameters and didn't add a paramaterless one.
A default parameterless constructor would look like:
Sprite()
{}
Be sure to do a lot more reading and tutorials. This is fairly basic class information.

WebApi Controller action parameter base class for common features

Where WebApi Controller actions share identical features, E.g. pagination and partial response, is it possible to create a base class to model these parameters?
For example, this URI:
http://letsdoitclean.com/api/v1/athletes?clean=true&fields=name,age&offset=0&limit=25
might map to:
class AthletesController
{
IHttp Get(bool clean, string[] fields, int offset, int limit)
{
...
}
}
However, fields, offset and limit are concepts that will be frequently used. So I want something like:
abstract class ActionParameter
{
public string[] fields;
public int offset;
public int limit;
}
class AthletesGetParameter : ActionParameter
{
public bool clean;
}
class AthletesController
{
IHttp Get(AthletesGetParameter param)
{
...
}
}
Can I do it?
This could also be achieved by adding it globally to your WebApiConfig so that you don't have to mark it up in every single controller action:
config.ParameterBindingRules.Insert(0, descriptor =>
typeof(ActionParameter).IsAssignableFrom(descriptor.ParameterType)
? new FromUriAttribute().GetBinding(descriptor)
: null);
Yes, absolutely you can do this. ASP.NET will handle the parameter binding if you, in this example, specify the FromUriAttribute for the complex object:
public class AthletesController : ApiController
{
public string Get([FromUri] AthletesGetParameter athletesGetParam)
{
// ...
}
}
The only thing I would argue against from your question, is the name of the abstract class. It doesn't really describe the base class all that well and what it's intended for. Maybe something like abstract class PaginationParameter or something similar. To call it ActionParameter could confuse you in the future (or other programmers) that all action parameters should derive this class, and I don't think that's right.
Maybe minutia on the naming of the base class, but to answer your direct question... yes you can do this.

Visual Studio 2010/2012/2013, Class Diagram: how to show interface as base class, not as "lillypop"?

Since the interface is already on the diagram I would like to show inheritance reference explicitly. But I can't find how...
There is a bug in VS 2005 up to 2012 that won't allow it to work.
I have a work arround that might trick it into drawing the inheritance for interfaces.
Say your interface is called IMyInterface. You have to replace it with an abstract class implementing that interface and use it instead of your interface. The code would make use of the conditional compilation and will look like this:
//to generate class diagram, add 'CLSDIAGRAM' to the conditional symbols on the Build tab,
// or add '#define CLSDIAGRAM' at the top of this file
#if CLSDIAGRAM
#warning CLSDIAGRAM is defined and this build should be used only in the context of class diagram generation
//rename your interface by adding _
public interface IMyInterface_
{
int MyProperty { get; }
void MyMethod();
}
//this class will act as an interface in the class diagram ;)
public abstract class IMyInterface : IMyInterface_ // tricks other code into using the class instead
{
//fake implementation
public int MyProperty {
get { throw new NotImplementedException(); }
}
public void MyMethod()
{
throw new NotImplementedException();
}
}
#else
// this is the original interface
public interface IMyInterface {
int MyProperty { get; }
void MyMethod();
}
#endif
That's likely to show it as you wish.
In your case IMyInterface will become IMedicine.

can i use accessors with an abstract class?

I have the following class that I am attempting to test
public abstract class MyClass<TU> : where TU : class, IMyInterface
{
protected virtual void ShowMessage(string message)
{
// do some work
}
protected IList<int> Items { get; set; }
// do some more work
}
I am testing with rhino mocks and mstest.
I want to be able to test the ShowMessage virtual method of the abstract class. To do such, I will need to create an accessor that can access the protected method of the class.
I generate the accessor in to my test project without issue.
However it causes the following build error:
GenericArguments[0], 'TU', on '"Namepace of IMyInterface".IMyInterface`1[TU]' violates the constraint of type parameter 'TU'.
Any ideas as to why this may be occuring and how to resolve it?

Visual Studio code generated when choosing to explicitly implement interface

Sorry for the vague title, but I'm not sure what this is called.
Say I add IDisposable to my class, Visual Studio can create the method stub for me. But it creates the stub like:
void IDisposable.Dispose()
I don't follow what this syntax is doing. Why do it like this instead of public void Dispose()?
And with the first syntax, I couldn't work out how to call Dispose() from within my class (in my destructor).
When you implement an interface member explicitly, which is what the generated code is doing, you can't access the member through the class instance. Instead you have to call it through an instance of the interface. For example:
class MyClass : IDisposable
{
void IDisposable.Dispose()
{
// Do Stuff
}
~MyClass()
{
IDisposable me = (IDisposable)this;
me.Dispose();
}
}
This enables you to implement two interfaces with a member of the same name and explicitly call either member independently.
interface IExplict1
{
string InterfaceName();
}
interface IExplict2
{
string InterfaceName();
}
class MyClass : IExplict1, IExplict2
{
string IExplict1.InterfaceName()
{
return "IExplicit1";
}
string IExplict2.InterfaceName()
{
return "IExplicit2";
}
}
public static void Main()
{
MyClass myInstance = new MyClass();
Console.WriteLine( ((IExplcit1)myInstance).InstanceName() ); // outputs "IExplicit1"
IExplicit2 myExplicit2Instance = (IExplicit2)myInstance;
Console.WriteLine( myExplicit2Instance.InstanceName() ); // outputs "IExplicit2"
}
Visual studio gives you two options:
Implement
Implement explicit
You normally choose the first one (non-explicit): which gives you the behaviour you want.
The "explicit" option is useful if you inherit the same method from two different interfaces, i.e multiple inheritance (which isn't usually).
Members of an interface type are always public. Which requires their method implementation to be public as well. This doesn't compile for example:
interface IFoo { void Bar(); }
class Baz : IFoo {
private void Bar() { } // CS0737
}
Explicit interface implementation provides a syntax that allows the method to be private:
class Baz : IFoo {
void IFoo.Bar() { } // No error
}
A classic use for this is to hide the implementation of a base interface type. IEnumerable<> would be a very good example:
class Baz : IEnumerable<Foo> {
public IEnumerator<Foo> GetEnumerator() {}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { }
}
Note how the generic version is accessible, the non-generic version is hidden. That both discourages its use and avoids a compile error because of a duplicate method.
In your case, implementing Dispose() explicitly is wrong. You wrote Dispose() to allow the client code to call it, forcing it to cast to IDisposable to make the call doesn't make sense.
Also, calling Dispose() from a finalizer is a code smell. The standard pattern is to add a protected Dispose(bool disposing) method to your class.

Resources