I've the following class
MyClass
{
public int Id {get;set;}
public string Name {get;set;}
public List<string> FriendNames {get;set;}
public MyClass()
{
FriendNames = new List<string>();
}
}
Is it correct to initialise the List like I've done or should it be
this.FriendNames = new List<string>;
Is there any difference ?
Then in my code I can create a instance like
MyClass oMyClass = new MyClass();
oMyClass.Id = 1;
oMyClass.Name = "Bob Smith";
oMyClass.FriendNames.Add("Joe King");
Here this.FriendNames = new List<string>; is exactly the same as FriendNames = new List<string>; this will count only when you will have variable with name same as your property.
like here:
public MyClass(List<string> FriendNames)
{
this.FriendNames = FriendNames; // here we have to specify which FriendNames is from this class
}
Constructor is for initializing some resources, so initializing your list there is a good idea.
You can create constructor with name and id (if you are always assigning them)
public MyClass(string name, int id)
{
FriendNames = new List<string>();
Name = name;
Id = id;
}
and change your code to:
MyClass oMyClass = new MyClass("Bob Smith", 1);
oMyClass.FriendNames.Add("Joe King");
You could do this.
private List<string> list = new List<string>();
public List<string> List
{
get { return list; }
set { list = value; }
}
Instantiating a list should be something like
FriendNames = new List<string>();
If you're asking whether the this is required, if your constructor took a list of FriendNames such that there is ambiguity in what you mean, then you'd have to use this to indicate that you want to assign it to the object's instance.
public MyClass(List<String> FriendNames)
{
this.FriendNames = FriendNames;
}
There is no real difference. So it boils down to preference.
Some people like to because it is very explicit and self commenting. Others feel that it clutters the code.
The important thing is that you are instantiating the List in the constructor. Something that too many people forget to do.
The accepted answer in this SO question has a nice list of when to use the this keyword
When do you use the “this” keyword?
If you are using this.FriendNames = new List<string>; you see that this is a class-variable with the first glance.
Especially in large classes with many variables this can be an advantage as you can easier/faster distinguish class-variables from local variables.
But as many other here stated this is up to your preference.
Where this is getting important is if you have a class and a local variable with the same name like this:
MyClass
{
public List<string> FriendNames {get;set;}
public SetMyList(List<string> FriendNames)
{
this.FriendNames = FriendNames;
}
}
In this case you have to use the this-keyword.
Use this to initialise an instance of your class
var x = new MyClass { Id = 1, Name = "Steve",
FriendNames = { "John", "Paul", "Ringo", "George" } };
And generally don't use "this." references, I rarely see it used in this way (often I use the only remnants of any kind of Hungarian notation left in my code by prefixing private fields with "_" so at least
public void DoSomething();
{
_myInt = 123;
}
private int _myInt;
public int MyInt { get { return _myInt; } }
Means I know whats going on, but I'm sure people out there won't like the "_".
It should be
FriendNames = new List<string>();
Or
FriendNames = new List<string>(123456);
if you know the capacity before upon initialization.
Related
After an extensive search, I ask here: is there a way to "apply" a hashtable to object properties? For example, if I have a class:
public class MyClass
{
public string PropertyOne {get;set;}
public int PropertyTwo {get;set;}
}
Now, if I have a Hashtable of:
var table = new Hashtable {
{ "PropertyOne", "My string"},
{ "PropertyTwo", 4 }
};
Can I plug the table into an instance of the class so that Object.PropertyOne becomes "My string", etc, without having to parse it myself?
What you are referring to is often referred to as a mixture between "auto-conversion" and "de-serialization". In this specific case it is most easily achieved via non-recursive reflection.
MyClass mine = new MyClass();
table.Cast<DictionaryEntry>()
.ToList()
.ForEach((entry) => {
var field = mine.GetType().getProperty((string)entry.Key);
field.SetValue(mine, entry.Value);
});
During the development of one of my projects, I encountered an issue regarding generic types.
The project requires me to write a class that would act as a source of list objects. Suppose I had the following class:
public class TablesProvider
{
private readonly List[] _tables;
public TablesProvider()
{
// initialize the tables var here....
}
public List<TItem> GetTable<TItem>()
{
return (List<TItem>)_tables.Single(x => x is List<TItem>);
}
}
This class obviously doesn't work, because the List type is a generic type and therefore the generic arguments should be specified.
So I made an abstract type called MyList, that would be derived by a more specific type MyList<TItem> in order to escape this requirement, and edited the TablesProvider a little.
public class TablesProvider
{
private readonly MyList[] _tables;
public TablesProvider()
{
// initialize the tables var here....
}
public MyList<TItem> GetTable<TItem>()
{
return (MyList<TItem>)_tables.Single(x => x is MyList<TItem>);
}
}
public abstract class MyList
{
// ...
}
public class MyList<TItem> : MyList, IList<TItem>
{
private readonly List<TItem> _elements = new List<TItem>();
public TItem this[int index]
{
get { return _elements[index]; }
set { _elements[index] = value; }
}
// ...
}
This works quite well. There is only one problem left. Suppose I had 45 different collections, each defined with a different generic argument. What would be the best way of initializing all of those collections? I cannot use a for loop here, since generic parameters are specified at compile-time and not at runtime, and therefore a construction like this wouldn't be possible:
for (int i = 0; i < 45; i++)
_tables[i] = new MyList<GenericParameters[i]>();
My ultimate goal is to have the luxury to just do something like this...
var table = _tablesProvider.GetTable<SomeClass>();
var element = table[3];
var propertyValue = element.SomeProperty;
... without the need to cast the variable element in order to access its type-specific members.
It is probably worth mentioning that the amount of different list objects is fixed to 45. This will not change. In theory, I could initialize the array line by line, or have 45 properties or variables instead. Both of these options, however, sound as a rather cheap solution to me, but I will accept one of them if there is no other way.
Any of you got some ideas? Am I doing this completely wrong? Should I consider an other structure?
Thanks in advance.
Yes, it is possible to do what you are describing if you use reflection.
Supposing that your hypothetical GenericParameters array is an array of Types (since you can't have an array of type identifiers), you can define this helper function:
private MyList MakeList(Type t)
{
return (MyList)Activator.CreateInstance(typeof(MyList<>).MakeGenericType(t));
}
And that will allow you to do this:
public TablesProvider()
{
var GenericParameters = new[] { typeof(string), typeof(int), typeof(DateTime) };
_tables = new MyList[GenericParameters.Length];
for (int i = 0; i < GenericParameters.Length; i++)
{
_tables[i] = MakeList(GenericParameters[i]);
}
}
You can even use LINQ if you want:
public TablesProvider()
{
var GenericParameters = new[] { typeof(string), typeof(int), typeof(DateTime) };
_tables = GenericParameters.Select(MakeList).ToArray();
}
Previous answer:
Well, the reality is that you're going to have a list of 45 different types somewhere, which pretty much means you're going to have 45 different lines of similar code. So one could say the goal is to make those lines as concise as possible.
One way to do so would be to add a helper function:
private void AddTable<T>()
{
_tables.Add(new MyTable<T>());
}
(this assumes changing _tables to a List<MyTable>)
Then you could just do:
AddTable<Type1>();
AddTable<Type2>();
AddTable<Type3>();
AddTable<Type4>();
this implementation works
public class TablesProvider
{
private readonly List<object> _tables;
public TablesProvider()
{
_tables = new List<object>();
}
public IList<TItem> GetTable<TItem>()
{
var lst = (List<TItem>)_tables.SingleOrDefault(x => x is List<TItem>);
if (lst == null)
{
lst = new List<TItem>();
_tables.Add(lst);
}
return lst;
}
}
it creates List of TItem when necessary; next time it returns the same list for TItem. it is lazy initialization
so you can do invoke
var table = _tablesProvider.GetTable<SomeClass>();
without any code like this:
for (int i = 0; i < 45; i++)
_tables[i] = new MyList<GenericParameters[i]>();
it is not ThreadSafe
I have a an object called FooObject:
public class FooObject
{
public string Test1 {get; set;}
public List<FooSubObject> SubTest1 {get; set;}
}
For later in the example, I also have a DifferenceFooObject:
public class DifferenceFooObject
{
public string SharedTest1 { get; set; }
public List<FooSubObject> SubTest1 {get; set;}
}
For later in the example, I also have a FooSubObject. FooObject has a property SubTest1 that contains a typed collection of this type:
public class FooSubObject
{
public string Test2 { get; set; }
}
I have a method that accepts a typed collection of FooObject. In this method, I need to calculate if any of the properties between the FooObjects within the typed collection parameter, have equal properties.
public DifferenceFooObject RunPropComparison(List<FooObject> foos)
{
DifferenceFooObject difference = new DifferencFooObject();
FooObject forComparison = foos.FirstOrDefault();
IEnumerable<FooObject> intersectCollection = foos.Skip(1);
// maybe do this using the first to compare the rest? No clue
}
I do not know the most efficient way to complete the above method. It is further complicated, at least IMHO, that the calculation has to take into account the properties of objects in collections that are a property of FooObject (looping through the properties of FooSubObject).
Here is the requested in/out:
List<FooObject> foos = new List<FooObject>();
FooObject obj = new FooObject();
obj.Test1= "Test1";
obj.SubTest1 = new List<FooSubObject>();
FooSubObject obj2 = new FooSubObject();
obj2.Test2 = "Test2";
obj.SubTest1.Add(obj2);
FooObject obj3 = new FooObject();
obj3.Test1= "Test1";
obj3.SubTest1 = new List<FooSubObject>();
FooSubObject obj4 = new FooSubObject();
obj4.Test2 = "Test3";
obj3.SubTest1.Add(obj2);
That's what would go in, ideally it would return that Test1 is the same across the board.
Best as I can tell, this is what you're looking for:
public IList<DifferenceFooObject> RunPropComparison(List<FooObject> foos)
{
var differences = new List<DifferenceFooObject>();
foreach (var group in foos.GroupBy(x => x.Test1))
{
var difference = new DifferenceFooObject();
difference.SharedTest1 = group.Key;
difference.SubTest1 = group.SelectMany(x => x.SubTest1).ToList();
differences.Add(difference);
}
return differences;
}
Or if you add the following constructor:
public DifferenceFooObject(string sharedTest1, IEnumerable<FooSubObject> subTest1)
{
this.SharedTest1 = sharedTest1;
this.SubTest1 = subTest1.ToList();
}
Then you can make this code shorter:
public IList<DifferenceFooObject> RunPropComparison(List<FooObject> foos)
{
return foos.GroupBy(x => x.Test1)
.Select(g => new DifferenceFooObject(g.Key, g.SelectMany(x => x.SubTest1)))
.ToList();
}
I don't think there is an especially efficient way of doing this. You will need to rely heavily on Reflection using the getProperties method to get at the values of the object properties...
You could look into using FasterFlect (http://fasterflect.codeplex.com/) which has better performance over standard .Net reflection...
Check out this library. It compares two objects and tells you the different properties http://comparenetobjects.codeplex.com/documentation
This might be lame, but here:
public interface Interface<T>
{
T Value { get; }
}
public class InterfaceProxy<T> : Interface<T>
{
public T Value { get; set; }
}
public class ImplementedInterface: InterfaceProxy<Double> {}
Now I want to create an instance of the ImplementedInterface and initialize it's members.
Can this be done somehow like this (using initialization lists) or the same behavior can only be achieved using the constructor with Double argument?
var x = new ImplementedInteface { 30.0 };
Can be done by:
var x = new ImplementedInteface { Value = 30.0 };
var x = new ImplementedInterface() { Value = 30.0 };
The only way to achieve what you're after is if your class implements IEnumerable<T> and has an Add method:
public class MyClass : IEnumerable<double>
{
public void Add(double x){}
}
Then you can do:
MyClass mc = new MyClass { 20.0 };
Obviously that's not what you want, because that doesn't set your Value and it allows you to add multiple values:
MyClass mc = new MyClass { 20.0, 30.0 , 40.0 };
Just go with the standard object initializes like others have pointed out:
var x = new ImplementedInterface() { Value = 30.0 };
You should be able to do:
var x = new ImplementedInterface {Value = 30.0};
var instance = new ImplementedInterface { Value = 30.0 }; will work. However, this isn't really the same set of operations as C++ initializer lists -- this is an object initializer. It initializes the new instance via the default constructor and then invokes the property setters for each property.
In other words, the object is constructed before the property setters run. If you want the values for the properties set before construction of ImplementedInterface completes, you'd have to write a constructor, as you noted. This distinction in behavior usually doesn't matter, but it's good to be aware of.
I am not sure if you have a special reason to use the interfaces that way but the following code might work for you.
public class ImplementedInterface2 : List<double> { }
public class test
{
public void x()
{
var x = new ImplementedInterface2() { 30.0 };
}
}
var x = new ImplementedInterface { Value = 30.0 };
You can definitely use an initialization list, but you have to specify what 30.0 is (this is true for any initialization list, not just the code you have):
var x = new ImplementedInteface { Value=30.0 };
Ok I have a class similar to the following...
public class Order
{
private Guid id;
[DataMember]
public Guid ID
{
get { return id; }
set { id = value; }
}
private List<Items> orderItems;
[DataMember]
public List<Items> OrderItems
{
get { return orderItems; }
set { orderItems= value; }
}
}
public class Items
{
private string itemName;
[DataMember]
public string ItemName
{
get { return itemName; }
set { itemName = value; }
}
}
When I reference in my code I have a method that takes in an "Order" list as the parameter.
ACME.Order newOrder = new ACME.Order();
ACME.Items newItems = new ACME.Items();
newOrder.ID = xxx
newItems.ItemName = xxx
SendOrderWithItemsFunction(newOrder)
The above works fine however I don't have an add function for my items so that I can do something like the following
newOrder.Items.Add(newItem);
and
newOrder.Items = newItems
will not work because it says that it can not implicitly convert newOrder.Items to newItems[].
What am Missing?
I think I might be missing something, but newOrder.OrderItems.Add(newItem) should work just fine, according to waht you have in your post.
Just some other nitpick things:
The pluralization of the "Items" class is wierd, if it is only a single Item. This is probably the reason that it looked "ok" to assign a single item to a List property.
You may have cut it out of your post, but every class that is being serialized by WCF must be marked as a "DataContract", not just the members of the class.
When initializing objects like this, I think it makes it a lot cleaer to use Type Initializers:
var NewOrder = new ACME.Order{
ID = xxx,
OrderItems = new List<ACME.Item>
{
new ACME.Item{
ItemName = xxx
}
}
};
What you do have is an add function in your Order.OrderItems property:
newOrder.OrderItems.Add(newItem);
you can even add a whole list of items to your OrderItems:
var someList = new List<Items>();
//populate someList here
newOrder.OrderItems.AddRange(someList);
You should be able to do:
newOrder.OrderItems.Add(newItem);
If your newItems[] is an array, you need to do this:
newOrder.OrderItems.AddRange(newItem.ToList<Items>());
You have declared newItems as an ACME.Items type, but the OrderItems property of your Order class is a List<Items>. Those types are not assignable from one to the other directly. So, an assignment of newOrder.OrderItems = newItems is like trying to sayList<Items> = Items. That isn't possible based on the classes you outlined above. Instead, you will need to add to the list.
When you have a list within a list, and the Add() method is missing, a workaround is to make a new list, add the items, then set the inner list to the new list. Instead of:
outerList.innerList.Add(item)
..use..
var newList = new List<ItemType>();
newList.Add(item);
outerList.innerList = newList;