Inner class within Interface in C# - c#

The following question shows how to implement an interface that contains a class in java:
inner class within Interface
The code in Java is:
public interface A {
class B {
}
}
I was hoping the same thing was possible in C#, though I haven't yet been able to get anything working.
For reference, I have a class which makes lookups of key values, but the keys aren't named in a way that makes them easy to understand. I'd like to have a compile time lookup for keys, so the interface would be something like:
interface Lookup {
class Keys {
string SomeKey() => "0"
}
}
Which means I suppose I have two questions:
Is it possible to have an interface containing a class?
Is there a better way of having a lookup between two strings (or any other values) that I can reference reliably at compile time?

Simply put no you can't have a class inside an interface.
From your comments you are talking about having a restricted list of available strings for the keys so I'm wondering if you are in fact not looking for a string/string lookup but just want a convenient way of referencing a list of fixed strings. So a class with constants is all you need:
public static class Strings
{
public const string AString = "A";
public const string BString = "B";
public const string CString = "C";
}
Accessed like this:
var s = Strings.AString;

You cannot have an class within an interface in C#. Interfaces are very simple in C#, and only provide a contract of functionality.
If you want to have a mapping between two strings, a Dictionary<string, string> may be of use to you.

An interface can't itself have any instance data. It's implementation however can have any instance data it requires.
For example, a random example that might give you some insight:
public class SomeClass
{
public string Key {get; set;}
}
public interface ISomeInterface
{
string Value { get; set; }
SomeClass SomeClass { get; set;}
}
public class SomeInterfaceImplementation : ISomeInterface
{
public SomeInterfaceImplementation()
{
SomeClass = new SomeClass()
{
Key = "ABC"
};
}
public string Value { get; set; }
public SomeClass SomeClass { get; set; }
}
public class Program
{
public static void Main()
{
var example = new SomeInterfaceImplementation()
{
Value = "A value",
} as ISomeInterface;
Console.WriteLine($"{example.SomeClass.Key} has value '{example.Value}'");
}
}
In the example, the default constructor "generates" a key of ABC. We could implement this any way your logic requires. But you also have a contract that requires "SomeClass" and it's key is present.
Anywhere you want to use the contract, just accept the Interface and not an implementation class.
Additionally, feel free to play with the fiddle:

Most of the answers under this question are no longer true.
Since C# 8.0, when default interface methods were added, it is possible for an interface to have member declaration that declare for example nested type.
The following code is correct for C# 8.0:
public interface IA
{
class B
{
}
}

Related

Something weird seems to have happened with C# classes

I used to be able to do this:
public class Something
{
public class SomethingElse
{
public static class ThisThing
{
public static string aoidj {get;set;}
}
}
}
But it no longer works.
My desired result (and what I've always been able to do) is:
Something.SomethingElse somethingElse = new Something.SomethingElse();
somethingElse.ThisThing.aoidj = "yay";
Console.WriteLine(somethingElse.ThisThing.aoidj);
But that no longer works. Instead of being able to access ThisThing from somethingElse, it's now appearing in SomethingElse.!
Has the C# language changed or something? The behaviour is definitely different and I don't know when it changed.
You need to do this:
Something.SomethingElse.ThisThing.aoidj = "yay";
Console.WriteLine(Something.SomethingElse.ThisThing.aoidj);
Or otherwise change your code to this:
public class Something
{
public class SomethingElse
{
public Whatever ThisThing = new Whatever();
public class Whatever
{
public string aoidj {get;set;}
}
}
}
And then you could do this (your desired result):
Something.SomethingElse somethingElse = new Something.SomethingElse();
somethingElse.ThisThing.aoidj = "yay";
Console.WriteLine(somethingElse.ThisThing.aoidj);
It has to appear in the SomethingElse., otherwise, how can you acces it, it is a Nested Type!
C# has not changed in this way. Nested Types have always been accessible through their parent types.
See my answer here: Cannot access nested classes or members of base class.
Besides, there is no point in having static classes as a Nested Type, since static classes are more commonly used as managers or providers, so they are mainly used elsewhere in your system.
Aside, if you want to access your static class members, you have to type in its name and access it once and for all.
Something.SomethingElse.ThisThing.aoidj
But I can't do that. It would be bad. I need to do it from somethingElse. Not SomethingElse.
Than make it a property rather than a class.
public class Something {
public class SomethingElse {
public OrEventSomethingElse ThisThing { get; set; }
}
}
public class OrEventSomethingElse {
public string aoidj { get; set; }
}
This way, you shall not be able to access it through your Nested Type SomethingElse, but rather through only an instance.
Some resources to help you understand OOP.
Object-Oriented Programming (C# and Visual Basic)
C# Tutorial - An Object Oriented Approach to Programming
Introduction to C# classes
C#.Net Tutorial 17-1 - Classes and Object-Oriented Programming (Part 1)
.NET Tutorial : Object Oriented Programming Using C# For Beginners - Part 1 - Introduction
Beginning C# Object-Oriented Programming
Object Oriented Programming using C# (DOWNLOAD FREE)
** I need it to be a class though, because there is more stuff to go inside of ThisThing**
Make it a class outside of SomethingElse so that you may access it as a simple instance member/property.
public class ThisThing {
public string Stuff { get; set; }
public int SomeMoreStuff { get; set; }
public DateTime EvenMoreStuff { get; set; }
// ...
public string ThisClassIsGettingHuge {
get {
return "Time to refactor because big classes tend to break SRP";
}
}
}
public class Something {
public class SomethingElse {
public ThisThing ThisThingAsAProperty { get; set; }
}
}
It is then, and only then that you shall only be able to access your instance.
var somethingElse = new Something.SomethingElse;
Console.WriteLine(somethingElse.ThisThingAsAProperty.ThisClassIsGettingHuge);
I have developed information and process for years, and I rarely use Nested Types. They generally cause more damage than they help.
Nothing is changed, but your code is wrong. And luckily I found answer too.
class Something
{
public class SomethingElse
{
public SomethingElse()
{
}
public static class sm
{
public static void set()
{
}
}
}
}
Use the class in this manner-
Something.SomethingElse.sm.set();

return a class containing generic List

I'm trying to construct a class in c# (5.0) that I can use as a base class and it contains a List, but List could be 2 different types. I want to do the following:
public class BaseC
{
string header { get; set; }
List<object> recs { get; set; }
}
public class derive1: BaseC
{
List<myclassA> recs;
}
public class derive2: BaseC
{
List<myclassB> recs;
}
and importantly what I want to do is return the derived classes from a method in another class:
public BaseC PopulateMyDerivedClass()
{
BaseC b = new BaseC();
b.header = "stuff";
b.recs = FileHelperEngine<myclassB> fhe.ReadStringAsList(x);
}
the main point is that method PopulateMyDerivedClass really does the exact same thing for both derive1 and derive2, just that it returns a different type of list.
I think I need generics. But is that at the base class level and also is PopulateMyDerivedClass then supposed to return a generic? I think that perhaps I am not dealing with polymorhpism, but as you can guess I am new to generics, so struggling.
I think what you want is to make BaseC a generic class and specify the generic when defining the derived classes:
public class BaseC<T>
{
//...
virtual List<T> Recs { get; set; }
}
public class Derived1 : Base<MyClassA>
{
override List<MyClassA> Recs { get; set; }
}
Good point by Alexei Levenkov:
Usual note: DerivedX classes in this case will not have common parent unlike original sample. One may need to add more layer of classes (as non-generic parent of BaseC) or use an interface if DerivedX need to be treated as having common parent/interface.
I get the feeling that your code design could use some rethinking. For one, typically when we talk about "polymorphism", we are usually talking about polymorphic behaviors (methods), rather than members. I think you might want to consider two classes that implement an interface that does all the things you want each class to do (parses data into its own type of list and acts on it as you need it to).
Nevertheless, without getting way into the details of your code, I think something like this might be what you were trying to achieve:
public class BaseC<T>
{
string header { get; set; }
public List<T> recs {get;set;}
}
and
public BaseC<T> PopulateClass<T>()
{
var b = new BaseC<T>();
b.recs = new List<T>();
T first = (T)Convert.ChangeType("1", typeof(T));
b.recs.Add(first);
return b;
}
And to check our sanity:
BaseC<String> d1 = PopulateClass<String>();
System.Diagnostics.Debug.Print(d1.recs.First().ToString());
System.Diagnostics.Debug.Print(d1.recs.First().GetType().ToString());
BaseC<int> d2 = PopulateClass<int>();
System.Diagnostics.Debug.Print(d2.recs.First().ToString());
System.Diagnostics.Debug.Print(d2.recs.First().GetType().ToString());
prints
1
System.String
1
System.Int32

Generic <T> and 2 base class inheritance

I have a question and am getting a little stumped on this one. It's probably easy but I'm just missing it.
If I have a class what contains necessary structures and the structures can inherit. I need a generic method what that an be passed to and then used. For example, let's say I have a structure Test, Test-A which inherits from Test. Then I have a MyTest and MyTest-B both which inherit from Test-A.
How can I create a method using T so that I can supply both MyTest and MyTest-B and I can use either of them in the method?
So:
public class Test
{
public int Hello {get; set; }
}
pubilc class Test-A : Test
{
public string Name { get; set; }
}
public class MyTest : Test-A
{
public string Last { get; set; }
}
public class MYTest-B : Test-A
{
public int Age {get; set; }
}
I need a method like:
private void MyList<T>(List<T> TestList) where T : **{not sure what this would be}**
{
TestList.Age = 10;
**OR**
TestList.Name = "Jane";
}
How or what am I missing (or not understanding) to be able to do that?
Any assistance would be greatly appreciated.
There is no constraint you could use which would match both of those conditions. The only way to handle this would be to use two, overloaded methods, as there is no shared contract.
Generic constraints only work if there is a base class or interface shared which all types implement, and use the same contract (ie: both have Name and Age properties).
How can I create a method using T so that I can supply both MyTest and
MyTest-B and I can use either of them in the method?
**TestList.Age = 10;**
...
How would this work if you passed in an object of type MyTest, given that MyTest doesn't have an Age property?

Inheritance variables in c#

Just for practice I'm trying to write a calculator program. To make it difficult I trying to use some of the advanced inheritance topics I've learned, but not really used. Lets say you have an interface named IMath with one method string DoMath(). Is it possible to have a variable written in the IMath interface that all classes implementing that interface would see new values? So for example my class Add : IMath would have the method DoMath() and in that DoMath() method would change the value of the variable double ITotal which all classes that implement the IMath interface would see the new value.
You cannot specify variables or fields in interfaces, you can only specify:
Methods
Properties
Indexers
Events
See the C# documentation on interfaces for more information about this.
An interface dictates expected behavior, it does not dictate expected implementation. A property can be read as "the ability to retrieve the value of X" or "the ability to provide the value of X", where as a variable is "the ability to store X". This is not the same thing, and interfaces cannot make that guarantee.
If you absolutely need to enforce the presence of a variable, you should use a base class. I would probably look into combining these things, use interfaces for the external interface (ie. how should my calculator function) and base class and inheritance to avoid rewriting the same code over and over.
It sounds like what you're looking for is an abstract base class.
One possible implementation of what you describe is shown below.
public abstract class MathBase
{
public double Total { get; protected set; }
public abstract string DoMath(double value);
protected double ParseValue(string value)
{
double parsedValue;
if (!double.TryParse(value, out parsedValue))
{
throw new ArgumentException(string.Format("The value '{0}' is not a number.", value), "value");
}
return parsedValue;
}
}
public class Add : MathBase
{
public override string DoMath(string value)
{
Total += ParseValue(value);
return Convert.ToString(Total);
}
}
If you wanted every instance of every class that inherits from MathBase to share the same Total value, you would declare it as static:
public abstract class MathBase
{
public static double Total { get; protected set; }
public abstract string DoMath(string value);
}
(although I'm not really sure why you would want this)
You could do something like this:
interface IMath
{
string DoMath();
}
abstract class MathBase : IMath
{
protected double Total { get; set; }
public abstract string DoMath();
}
class Add : MathBase
{
public override string DoMath()
{
this.Total = 2;
return "2";
}
}

Why can't .Net / C# understand interface inheritance with properties of the same name?

Consider the following class and interfaces:
public interface A { string Property { get; set; } }
public interface B { string Property { get; set; } }
public interface C : A, B { }
public class MyClass : C
{
public string Property { get; set; }
}
Looks simple, right? Now consider the following program:
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Property = "Test";
A aTest = myClass;
B bTest = myClass;
C cTest = myClass;
aTest.Property = "aTest";
System.Console.WriteLine(aTest.Property);
bTest.Property = "bTest";
System.Console.WriteLine(bTest.Property);
cTest.Property = "cTest";
System.Console.WriteLine(cTest.Property);
System.Console.ReadKey();
}
Looks okay, but it will not compile. It gives me an Ambiguity exception:
Why isn't C# able to figure this out? Is what I'm doing crazy from an architectural point of view? I'm trying to understand the why (I know it can be solved with casting).
EDIT
The problems arose when I introduced interface C. When I use MyClass : A, B I've got no problems at all.
FINAL
Just finised a blog about the subject: Interface Ambiguity and Implicit Implementation.
In short because it's ambiguous indeed.
Now more detailed story. As you've already seen there is explicit interface implementation, so you can have two different implementations for A.Property and B.Property and when you have only C there is no way you can tell if implementations are the same or not. Since C# "philosophy" is not to guess what you meant, but make you state it more clear when necessary, compiler does not choose either A.Property or B.Property, but reports an error.
You need explicit interface implementation:
public interface A { string Property { get; set; } }
public interface B { string Property { get; set; } }
public interface C : A, B { }
public class MyClass : C
{
string B.Property { get; set; }
string A.Property { get; set; }
}
When it comes time to call them you are going to have to do:
MyClass c = new MyClass();
Console.WriteLine("Property A is ": ((A)c).Property);
Why don't you do:
public class MyClass : C
{
string B.Property { get; set; }
string A.Property { get; set; }
string B { get { return B.Property; } set { B.Property=value; } }
string A { get { return A.Property; } set { A.Property=value; } }
}
And it should be noted this is bad design, if you are going to expose an interface C, make sure you find a better way to expose A/B.Property.
What's to figure out? cTest is of type "C", and it inherits "Property" from two different classes; the compiler doesn't know which one you want. This sort of behavior is inherited from C++; it's the classic example of "why multiple inheritance is a Pandora's box."
Other object-oriented languages -- Java is a notable example -- avoid this problem by definition : like-named/like-signatured methods are fused in a common descendent.
When you inherit from a single interface the compiler can determine exactly which method you are interested in implementing when you add the new method.
However when multiple interfaces have the same method, the underlying (and correct) assumption is that each interface expects a DIFFERENT implementation for the method, due to the fact that those methods or properties are defined on different interfaces.
So the compiler tells you that these different interfaces require an explicit implementation for each of these properties.
The fact that two interfaces share the same NAME for a property or method is arbitrary - there is no reason to assume that they share anything OTHER then the name, so the compiler protects you from making the mistake of implicitly treating them in the same way.
It is not simple, and it doesn't look simple either. In case of a name collision between two interfaces, .NET needs to ask you which interface are you trying to implement. Its way to ask you this is via the ambiguity error.
If you didn't have this kind of errors, you would end up implementing interfaces by chance.
you need to explicity implement both properties from each interface:
public class MyClass : C
{
string A.Property { get; set; }
string B.Property { get; set; }
}
Because what you are doing is not right. A and B are clashing and have the same name for the property... you need to use Explicit implementation of interface.
Reference here.
There are a lot of answers, and all of them are right, as explicit interface implementation is the answer to your problem.
I'll try to clarify the motivation behind this design with a somewhat convoluted example:
Let's say I have an interface for people that run (with possible implementations like LongDistanceRunner, Jogger, MarathonMan, etc)
public interface IRunner
{
void Run();
}
and an interface for devices that can be turned on and ran (with possible implementations BathTub, Application, Dishwasher, etc)
public interface IRunnable
{
void Run();
}
Now I want to create and interface for a IMusicallJogger (implementations like JoggerWithIpod,BoomBoxJogger, etc)
public interface IMusicalJogger : IRunner, IRunnable {}
public class BoomBoxJogger : IMusicalJogger
{
// code here
}
BoomBoxJogger bbJogger = new BoomBoxJogger();
Now, when I say bbJogger.Run() what should my object do? Should it start running across the park, or should it turn on the boombox, or both, or something else entirely? If I implement both the class and the callsite, it might be obvious that I want my joggers to do both, but what if I control just the callsite? And what if there are other implementations of the interface that do something else? And what if my jogger starts running across the park, when it's used in a context where it is considered like a device (through casting).
That's where explicit interface implementation comes into play.
I have to define my class like this:
public class BoomBoxJogger : IMusicalJogger
{
void IRunner.Run() //implementation of the runner aspect
{
Console.WriteLine("Running through the park");
}
void IRunnable.Run() //implementation of the runnable aspect
{
Console.WriteLine("Blasting out Megadeth on my boombox");
}
public void Run() //a new method defined in the class itself
{
Console.WriteLine("Running while listening to music");
}
}
and then, when I call, I have to specify what aspect of my jogger I want to use:
BoomBoxJogger bbJogger = new BoomBoxJogger();
((IRunner).bbJogger).Run(); // start running
((IRunnable).bbJogger).Run(); // blast the boombox
//and of course you can now do
bbJogger.Run //running while listening
((IMusicalJogger)jogger).Run(); //compiler error here, as there is no way to resolve this.
Hope I helped clarify the concept.

Categories

Resources