I am looking at this code from a peer of mine and am a little confused as to how this makes sense:
public class CA
{
public CurrType CT {get; set;}
}
public interface ICharge
{
CA a {get; set;}
CurrType CT {get; set;}
}
public enum CurrType {X=0, Y=1}
public class Ch : ICharge
{
public CA a {get; set;}
public CurrType CT {get; set;}
}
I understand that interfaces contain properties but cant make any sense of the above code specifically:
1) Can the interface ICharge contain a class as a property?
2) Isnt some circular reference going on?
Isnt some circular reference going on?
No, there is no circular reference going on.
Can the interface ICharge contain a class as a property?
It sure can - why did you think it couldn't? This is perfectly normal usage - the interface is specifying that that property will contain an instance of that class (i.e. an object of that type). Why a class? Because classes are everywhere - even a lot of the basic .Net types are classes. A string is a class. You can't do everything with primitive value types :)
I can't answer why there is two different usages of CurrType in Ch (one at the root level, one in the CA instance), that's for you to figure out.
Related
What I seek to do is that define a generic type ClassB<TA> that would accept the TA type parameter to be assigned any type implementing a generic interface IInterfaceA<TB> but in whatever a way [the interface definition allows], regardless the type parameter TB that has been passed to it (IInterfaceA) in the TA implementation. I would also like to be able to access the type parameter (TB) that has actually been passed to the IInterfaceA interface by the particular TA implementation being used in the ClassB<TA> definition. Is this possible in C#? If yes, then what is the correct syntax?
E.g. something like the following (not particularly useful though seemingly illustrating, I hope) but syntactically and semantically correct:
public interface IInterfaceA<TB>
{
TB TheProperty {get; set;}
}
public class ClassB<TA> where TA : IInterfaceA<TB>
{
TA TheProperty {get; set;}
TB ThePropertyProperty => TheProperty.TheProperty;
}
UPDATE: I have actually went the following way so far (before having decided to ask if a better one may happen to exist), including TB (The IInterfaceA type parameter) itself in the definition of the ClassB but I am still curious if ClassB can be defined the way that would just allow all IInterfaceA implementations and derive/import the IInterfaceA type parameter a way implicitly (not 100% sure but seems actually making logically-definite (non-ambiguous) strong-typing sense while increasing code reusability to me, that's why I have guessed such a feature has a chance to actually exist).
public class ClassB<TA, TB> where TA : IInterfaceA<TB>
{
TA TheProperty {get; set;}
TB ThePropertyProperty => TheProperty.TheProperty;
}
UPDATE2: Given the original example and an example of an existing alternative provided it can probably be worth emphasizing on that a particular type meant (by an actual application design) to be assigned to the TA parameter at the instance definition time can happen to be a non-generic class, a completely-defined implementation of IInterfaceA with TB assignment hardcoded in its source (because no other types can make sense to be used instead of it in the context of particular-case logic parts this specific class implements perhaps), excepting no type arguments already (and I feel that what has already been defined should be referenced rather than re-defined a potentially "I remember it has been assigned X the last time" kind of way, for sake of avoiding creating soil for bugs and errors to emerge on at least, not to mention aesthetics/readability, maintainability, eliminating needs for copy-paste definitions of logical analogues targeting slightly different cases etc). The alternative solution mentioned means explicitly defining what is rather straight-forward to be unambiguously figured out by the compiler (at least in cases when the same interface is not implemented twice with different type arguments, thanks to #vyrp for highlighting the possibility of ambiguity in the multiple implementation case) given the usage context (what I consider not only a way handier, but also less bug-prone) and limiting the generic code re-usage opportunities. I believe this remark can explain why a less-verbose alternative to the ClassB<TA, TB> where TA : IInterfaceA<TB> syntax (as a way of implementing the logic described above) can make sense to seek at all.
The most immediate way to make this compile is this:
public interface IInterfaceA<T>
{
T TheProperty {get; set;}
}
public class ClassB<TA, TB> where TA : IInterfaceA<TB>
{
TA TheProperty {get; set;}
TB ThePropertyProperty => TheProperty.TheProperty;
}
But I'm not sure that I follow exactly what you're asking.
I'm not sure if this is what you mean by "nicer", but sometimes you can use a static outer class to allow one generic parameter to be inferred while explicitly providing the other:
public static class Helper<TB>
{
public static ClassB<TA> Create<TA>() where TA : IInterfaceA<TB>
{
return new ClassB<TA>();
}
public class ClassB<TA> where TA : IInterfaceA<TB>
{
TA TheProperty { get; set; }
TB ThePropertyProperty => TheProperty.TheProperty;
}
}
In UPDATE2, the PO says: "straight-forward to be unambiguously figured out by the compiler".
I beg to differ.
Let's suppose you have a class like this:
public class Impl : IInterfaceA<int>, IInterfaceA<string>
{
public int TheProperty { get; set; }
string IInterfaceA<string>.TheProperty { get; set; }
}
If you call ClassB<Impl>, what should TB be then?
That being said, let's dive in one possible implementation.
WARNING: this is not good-practice code! It is only supposed to show the mechanics of the language. The answer by #Enigmativity is how I would do it (aka, writing ClassB<TA, TB> where TA : IInterfaceA<TB>).
An option could be to define a base non-generic IInterfaceA. The tradeoff would be that ThePropertyProperty would have to be object.
Let be the definitions:
public interface IInterfaceA
{
object TheProperty {get; set;}
}
public interface IInterfaceA<TB> : IInterfaceA
{
new TB TheProperty {get; set;}
}
public class ClassB<TA> where TA : IInterfaceA
{
public TA TheProperty {get; set;}
public object ThePropertyProperty => TheProperty.TheProperty;
// You can choose to write here either "IInterfaceA`1" or typeof(IInterfaceA<>).Name
public Type TypeOfTB => typeof(TA).GetInterface("IInterfaceA`1").GetGenericArguments()[0];
}
public class Impl : IInterfaceA<int>
{
public int TheProperty { get; set; }
object IInterfaceA.TheProperty
{
get { return TheProperty; }
set { TheProperty = (int)value; }
}
}
Then the following code compiles and runs successfully:
void Main()
{
var impl = new Impl{ TheProperty = 42 };
int i = impl.TheProperty;
Console.WriteLine(i);
var b = new ClassB<Impl>{ TheProperty = impl };
i = (int)b.ThePropertyProperty;
Console.WriteLine(i);
Console.WriteLine(b.TypeOfTB.Name);
}
With output:
42
42
Int32
For bonus I've added how to get TB at runtime.
I have the following code:
public Abstract class BaseClass
{
public int BaseProperty {get; set;}
}
public class ChildClass : BaseClass
{
public int ChildProperty {get; set;}
}
public class test
{
public test()
{
ChildObject = new ChildClass ();
}
public ChildClass ChildObject {get; set;}
}
In class test I want to access the property BaseProperty of the base class, ChildObject.BaseProperty doesn't work and if I did
int num = (ChildObject as BaseClass).BaseProperty ;
a conversion error occurs.
Any idea?
Just use b.P1. (Here's a DotNetFiddle for convenience because I'm all about convenience.)
Think of it like this: B inherits from A. So even though P1 is technically a property of A, B also has that property because it inherits from A. You can always treat an instance of B as if it's an instance of A.
Side note - I've noticed that both the questions and answers are a little easier to read if we avoid using names like A, B, BaseClass, InheritedClass, etc.
So here's the same explanation using some more verbose examples. "Car" is seriously overused, but I'm going to use it anyway.
public class Vehicle
{
public int NumberOfDoors {get;set;}
}
public class Truck : Vehicle
{
public int NumberOfCountryMusicianEndorsements {get;set;}
}
If you create a new instance of Truck
var truck = new Truck();
You can cast it as a Vehicle
var vehicle = (truck);
var numberOfDoors = vehicle.NumberOfDoors;
But you don't need to because vehicle is already a Vehicle because Truck inherits from Vehicle. So Truck has the same properties as Vehicle plus its own.
var numberOfDoors = truck.NumberOfDoors;
There's even a fancy term for this - it's called the Liskov Substitution Principle. In brief, it means that if Truck inherits from Vehicle then you should be always be able to use a Truck as a Vehicle. You can always substitute an inherited class for any one of its base classes. (That's not always true. Sometimes you can't. That means someone did something wrong. The principle means that you should always be able to.)
I think you have a variable spelling error , in A you define P1 using upper case and in B you define p2 using lower case , be consistent in naming and accessing b.p1 will work
I tried to inherit interface, and make some of the automatically generated set property as private. This is an example.
public class MyClass
{
public interface A
{
int X {get; set;}
}
public interface B : A
{
int Y {get; set;}
}
public class C : A
{
public int X {get; private set;}
}
When I tried to compile it. I got an error 'MyClass.C' does not implement interface member 'MyClass.A.X.set'. 'MyClass.C.X.set' is not public..
I tried with private set; in iterface A, but I got this error again : 'MyClass.A.X.set': accessibility modifiers may not be used on accessors in an interface.
Is this accessibility modifier not allowed in C#?
I tried with private set; in iterface A, but I got this error again
If your interface only requires that a property should be retrievable, you define it as:
public interface A
{
int X {get;} // Leave off set entirely
}
The declaration of an interface defines the public set of members that the implementing type must have. So, if C implements A, it must have a public member for each member defined by the interface.
A defines that any implementing type must have a public property X with a public getter and a public setter. C does not meet this requirement.
You can think of an interface as the minimum functionality that your class must implement. If the interface specifies that a property exposes a get and a set clause, then you must implement a public get and set clause in your class, because only public methods and properties can implicitly implement interfaces.
You can simply leave out the set keyword in the interface property definition if you don't want to expose a public mutator. Then you can make the implementation mutator either public or private.
No it is not allowed. Remember, code which is using an instance of class C must be able to treat it as an interface A, which means that the contract is a public getter and setter for property X.
This applies to class inheritance as well as interface inheritance -- you must follow the contract of the type you are derived from.
If the intent of the code is that property X should not have a public setter, then the interface should be defined with just the { get; }
I believe interface members must be public if the interface itself is public. Your implementation of the property is faulty because of that.
Why it is not ok to use IEnumerable<T> as a type for a property within a class
for instance something like
public class Example
{
public IEnumerable<Int32> Ids {get; private set;}
publicIEnumerable<string> Names {get; private set;}
}
Sorry the problem was not that it wasn't compiling, I missed the public accessors on writing the stuff here, the question was why not to use IEnumerable for a property. But as I read further, I realized that if we only need something to iterate through and not modify (add, remove) than this (using IEnumerable ) is perfectly acceptable.
The problem is that the default accessibility of members in classes is already private, so your code is equivalent to:
public class Example
{
private IEnumerable<int> Ids {get; private set;}
private IEnumerable<string> Names {get; private set;}
}
That fails to compile because when you include an extra access modifier for a getter or setter, it has to be more restrictive than the overall access of the property. It isn't in this case.
If you make the overall property public though, it will compile with no problems:
public class Example
{
public IEnumerable<int> Ids {get; private set;}
public IEnumerable<string> Names {get; private set;}
}
(That's assuming you have a using directive for the System.Collections.Generic namespace, of course.)
We have two classes that have the exact same public accessors (and many of them) but are from different areas in the object hierarchy; we have a need to copy and compare between these two objects. We could manually write a copy constructor and a comparison operator which compares the values of the same-named accessors, but it seems as though there's got to be a better way to do this using reflection and LINQ.
Example: we have class ClassA which has 70 accessors; we also have class ClassB which has 70 accessors, which are defined to be the same name and type as ClassA's accessors.
public class ClassA
{
int OneInt {get; set;}
int TwoInt {get; set;}
...
string OneString {get; set;}
string AnotherString {get; set;}
}
public class ClassB
{
int OneInt {get; set;}
int TwoInt {get; set;}
...
string OneString {get; set}
string AnotherString {get; set;}
}
What I'd like is a simple way of using reflection to discover all of the public accessors of ClassA, and use those names to set the values of the respective accessor on ClassB to the value of the accessor on ClassA. Roughly, in psuedocode:
foreach (string accName in ClassA.Accessors[])
BInstance.Accessors[accName].Value = AInstance.Accessors[accName].Value;
And, of course, the same thing could be used for testing equality between the two classes. My knowledge of C# reflection and LINQ is not good enough to know how to get this done, but I'd swear it's something relatively simple.
How about using AutoMapper:
Mapper.CreateMap<ClassA, ClassB>();
and then:
ClassA classA = ...
ClassB classB = Mapper.Map<ClassA, ClassB>(classA);
It's basically an implementation of your pseudo-code.
your rough pseudocode is somewhat accurate. Let me clean it up a little:
foreach (var propertyA in typeof(ClassA).GetProperties())
{
var propertyB = typeof(ClassB).GetProperty(propertyA.Name);
var valueA = propertyA.GetValue(objectA, null);
propertyB.SetValue(objectB, valueA, null);
}
Obviously, this doesn't do error checking, and stuff like that, but it should do the job.
You could do it in Linq, but I don't think it would be cleaner.