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.)
Related
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.
I have a class :
public class Foo {
// here so serializer can materialize the class
public Foo(){
}
public Foo(string bar){
ImportantStuff = bar;
}
public string ImportantStuff { get; set;}
public string OtherBits{ get; set;}
public int eresting { get; set;}
}
How can i protect ImportantStuff being set by anyone except the serializer (json.net/ EF) ?
You can place access modifiers on property accessors.
[JsonProperty]
public string ImportantStuff { get; private set; }
// ^^^
If you really must prevent Foo members from changing it, use a private setter AND move the property to a base class. But I interpreted the question to mean that you don't want consumers of the class to be able to set it.
The JsonProperty attribute is required because JSON.net will default to skipping properties with non-public setter. See Private setters in Json.Net and http://daniel.wertheim.se/2010/11/06/json-net-private-setters/
(Naturally other code that runs with full permission can do anything it wants to the insides of your object, if the right hoops are jumped through)
My textbook is referring to the this reference and it first implies that a property is somewhat static and does not store one with each object, but one for the entire class. Then later it says that a property is nonstatic. I am really confused. What is it?
Properties can be static or not static.
Static properties have the 'static' keyword, default is not static.
Properties that are static are stored for the entire class (there is only one).
Properties that are not static are stored per instance.
A property can be both static and non-static you decide which by using the static keyword.
public static int StaticProperty {get; set; }
public int InstanceProperty {get; set; }
On a side note, a property is actually two methods (or just one if you only implement the set or get).
public int MyProperty {get; set; }
is equivalent to
public void set_MyProperty(int value);
public int get_MyProperty();
In VB.NET it is possible to do the following in a class.
Public Property MyProperty As String
At this point a getter and setter is automagically created for you and you can refer to variable defined by the property as such.
Me._MyProperty = "BlahBlah"
Is there an equivalent mechanism in C# ?
public string MyProperty {get; set;}
by default they are both public accessors, you can make one of them private like this:
public string MyProperty {get; private set;}
In C# you cannot refer to the underlying variable of auto implemented properties directly.
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.