Passing a List<T> and a bool - c#

What is the best way of passing both a List<T> and a bool as the returning value of a method? Right now I have this custom class called BoolList acting like a container but I was wondering if there is a better and/or more elegant way of doing it.

Why not use a tuple?
http://www.dotnetperls.com/tuple
http://msdn.microsoft.com/en-us/library/dd268536.aspx
Then you have a type-safe container without having to create a class.
private Tuple<List<int>, bool> myMethod()
{
var myList = new List<int>();
var myBool = true;
return new Tuple<List<int>, bool>(myList, myBool);
}

You can use Tuple<List<T>, bool>
public Tuple<List<string>, bool> MethodName()
{
return Tuple.Create(new List<string>(), true);
}
or make the List<T> out parameter and return bool as normal one (like TryParse methods do)
public bool MethodName(out List<string> results)
{
results = new List<string>();
return true;
}

As already mentioned here, you can use a tuple and that is a good solution. The only drawback being that you refer to the items in the tuple with the non-informative names Item1, Item2... If you are going to be returning the same types often or you will be passing the result around where descriptive properties improve readability, then the other (old-fashioned) way is to have a class (or struct as described further down in this answer) with the return types as properties and return an instance of the class. For example a class definition could be local to your current class.
public class EmployeeSearchResult
{
public List<Employee> Employees{get;set;}
public bool Success{get;set;}
}
private EmployeeSearchResult Search()
{
var employeeSearchResult = new EmployeeSearchResult();
employeeSearchResult.Employees = new List<Employee>();
employeeSearchResult.SearchSuccess = true;
return employeeSearchResult;
}
Since the return is often small and lightweight with a short lifespan a struct may be a better option than a class. However, be aware of when a struct is appropriate - as per msdn: -
√ CONSIDER defining a struct instead of a class if instances of the
type are small and commonly short-lived or are commonly embedded in
other objects.
X AVOID defining a struct unless the type has all of
the following characteristics:
It logically represents a single value, similar to primitive types (int, double, etc.).
It has an instance size under 16 bytes.
It is immutable.
It will not have to be boxed frequently.

Related

Covariance in c# is not type safe. This statement applies fine when dealing with arrays, but not when dealing with Ienumerables. Why?

Case 1 : Covariance in arrays.
object[] array = new String[10];
// The following statement produces a run-time exception.
array[0] = 10;
Case 2 : Covariance in IEnumerable.
IEnumerable<Object> l1 = new List<string>();
// The following line executes just fine.
l1 = l1.Append(33);
We are implementing same scenario, i.e. putting an object of Array/List of more derived type (string), in a variable of less derived type (object), and then trying to add an element of type int.
Another related observation:
Consider we have following set of classes:
public class Bird { }
public class Pegion : Bird { }
public class BirdCalculations<T>
{
private T TField;
public void SetTField(T value)
{
this.TField = value;
}
}
In this scenario, consider the following code:
public static void Main() {
BirdCalculations<Bird> bc2 = new BirdCalculations<Pegion>(); //Line 1
BirdCalculations<Bird> bc1 = new BirdCalculations<Bird>();
bc1.SetTField(new Pegion()); //Line 2
//Now, Line 2 makes sense, but what is the problem with Line 1?
}
If your class is the receiving end of T-type parameter e.g. having method foo(T bar), you need a contravariance of T and not covariance, which is denoted as in T in C#. It also has to be an interface or delegate, so it is not possible to allow assignment of BirdCalculations<T1> instance to BirdCalculations<T2> reference or vice versa or whatever, no matter how T1 and T2 are related. It has to be IBirdCalculation<T1> bc = new BirdCalculation<T2>() or something like that. Here is the example modified from your code:
public class Bird { }
public class Pegion : Bird { }
public interface IBirdCalculations<in T> {
void SetTField(T value);
}
public class BirdCalculations<T> : IBirdCalculations<T>
{
private T TField;
public void SetTField(T value)
{
this.TField = value;
}
}
class Program
{
static void Main() {
IBirdCalculations<Pegion> bc2 = new BirdCalculations<Bird>(); //Line 1
IBirdCalculations<Bird> bc1 = new BirdCalculations<Bird>();
bc1.SetTField(new Pegion()); //Line 2
}
}
Notice that you cannot assign an instance of BirdCalculations<Pegion> to IBirdCalculations<Bird> reference because if that were possible somebody might invoke something like SetTField(parrot) and that shouldn't be allowed.
PS: Arrays in C# is not a variance, it is somehow historically allowed to be used like that but it actually breaks type-safe system. My best guess is that it was necessary when we had no generic in .NET which is like 15+ years ago.
This isn't doing what you think it is;
IEnumerable<Object> l1 = new List<string>();
// The following line executes just fine.
l1 = l1.Append(33);
First you're assigning a list to l1, as you expect. But then you're calling IEnumerable<>.Append() which is equivalent to;
public static IEnumerable<T> Append<T>(this IEnumerable<T> source, T obj)
{
foreach (var s in source)
yield return s;
yield return obj;
}
In other words, Append create a new IEnumerable that can be used to visit each element of your list, then the value you appended.
Covariance is safe for reading, but not for writing. When using an array, you can set a value in the array to an arbitrary type - this is not type safe, and that's the unwanted type escape. The same way, contravariance is safe for writing, but not for reading. Unfortunately, there were no ways to constrain variance in arrays back when that was implemented, other than making them entirely type invariant - which would severely limit code reuse without generics (just imagine how something like Array.Sort would work).
You cannot change an enumerable. Enumerables are read only. You did not add any item to the enumerable, and you didn't "modify" anything inside that enumerable. What Append does is create a new IEnumerable<object>. There's no type safety violation. To get a mental picture, you can imagine the new enumerable containing the old enumerable - but it doesn't change anything. All of the items that the enumerables might return still satisfy the original constraint - they're all object.

C# Dictionary of generic classes

I am new to C#. I am trying to implement a Dictionary in C# whose Java-equivalent is:
HashMap<string, Variable<?>> dictionary
Here is the detailed Java version of what I'm trying to do: Java how to manage user-defined variables
In C# so far I have something like this:
interface IVariable { }
public class Variable<T> : IVariable
{
public T myValue { get; set; }
}
Dictionary<string, IVariable> vars = new Dictionary<string, IVariable>();
Then I try to do this:
Variable<int> age = new Variable<int>();
age.myValue = 12;
vars.Add("age", age);
IVariable theVar;
if (vars.TryGetValue("age", out theVar) {
Console.WriteLine("fetched age is " + theVar.myValue);
}
I run into trouble in the last line because the compiler doesn't recognize the myValue member of a theVar because it is an IVariable.
In this simple example maybe I could declare theVar to be a Variable<int> instead of an IVariable but I haven't tried it because it would require a priori knowledge about what kind of variable I'm fetching from the dictionary and I might not always have that knowledge.
I wouldn't mind if myValue were an inherited/abstract property (if there is such a thing), since every Variable will have a property named myValue (each will differ in type but not in name). In that case I guess I could make IVariable an abstract class rather than an interface, but then I still run into trouble as far as what to put for the type of myValue.
Could I do a cast of theVar into something using as by first checking its type with is? I'm not sure if that would work or is even possible.
I've looked at these posts for guidance (especially the second one):
Wildcard equivalent in C# generics
C# Generics: wildcards
However, my situation is still slightly different than the second example above because that example has an abstract method that is returning a void whereas I wish to have my variables return non-void generic values.
Thanks for any help.
C# has dynamic. You can create Dictionary<string, dynamic>
Or you can use object (boxing/unboxing) Dictionary<string, object>
Or you can get generic type from class
class MyClass<TDicValue>
{
Dictionary<strint, TDicValue> myDictionary;
}
I had this same problem where I had 20 slightly different types and I had to keep dictionaries on. I wanted to organize them in a list.
The problem was the same, selecting the right kind from the list with reflection or strings lacked the ability to provide a type to return to. #skrilmps answer is correct, but packing and and unpacking was at best unreliable without a lot (metric ton) of ugly messy code.
While unity does support dynamics in 2020, this doesn't exactly work with what i am doing unless I make like everything dynamic safe and that's shamble coding, not extensible or maintainable, and just sounds like a general nightmare.
I personally feel that I am an inadequate programmer after years of trying to learn and still not having my efforts provide a productive return or product of note, so i cannot claim the answer being mine, but in my research on the proper solution to this problem i found this: https://www.youtube.com/watch?v=A7qwuFnyIpM
In here he says basically if you add an interface to your similar classes that are intended for use in a variety of different lists, that you can instead make a list of that type of interface. I would assume dictionary as well, and then you can add any kind of class implementing this interface to this singular interface type defined list.
I tried using boxing/unboxing and came up with this solution. It appears to work... so far. But it doesn't seem very safe.
public interface Variable
{
object getValue();
void setValue(object value);
Type myType();
}
public class Variable<T>: Variable
{
private T myValue;
public object getValue()
{
return myValue;
}
public void setValue(object value)
{
myValue = (T)value;
}
public Type myType() { return myValue.GetType(); }
}
Dictionary<string, Variable> vars = new Dictionary<string, Variable>();
Variable<int> age = new Variable<int>();
age.setValue(21);
vars.Add("age", age);
Variable theAgeVar;
vars.TryGetValue("age", out theAgeVar);
Console.WriteLine("age = " + theAgeVar.getValue());
Variable<double> height = new Variable<double>();
height.setValue(5.9);
Variable theHeightVar;
vars.TryGetValue("age", out theHeightVar);
Debug.Log("height = " + theHeightVar.getValue());
This prints:
age = 21
height = 5.9
One thing I do not like is that I had to make the return type of getValue() be an object. If I wanted myValue (which is of type T) to implement IComparable, for instance, then this information is lost when the boxing happens and the caller receives an object.
// The following should resolve the boxing problem and now is totally generic:
public interface IVariable<T>
{
T GetContent();
void SetContent(T value);
Type GetDataType();
}
public class Variable<T> : IVariable
{
private T content;
public T GetContent()
{
return content;
}
public void SetContent(T value)
{
content = value;
}
public Type GetDataType() { return GetType(); }
}
Dictionary<string, Variable<T>> variables = new Dictionary<string, Variable<T>>();

Convert object to struct with generics

I'm looking for a way to convert an object to one of several different types of structs. I need structs because I need it to be non-nullable. I'm not sure how to go about this, but this is what I've tried so far and it doesn't work because:
"Object must implement IConvertible." <- trying Convert.ChangeType
public class Something
{
private object[] things;
public Something()
{
//I don't know at compile time if this will
//be an array of ThingA's or ThingB's
things = new object[1];
things[0] = new ThingA();
ThingA[] thingsArrayA = GetArrayofThings<ThingA>();
things[0] = new ThingB();
ThingB[] thingsArrayB = GetArrayofThings<ThingB>();
}
public TData[] GetArrayofThings<TData>() where TData : struct
{
return (TData[])Convert.ChangeType(things, typeof(TData[]));
}
}
[Serializable]
public struct ThingA
{
//...
}
[Serializable]
public struct ThingB
{
//...
}
This is the working implementation thanks to Serg's answer:
public TData[] GetArrayofThings<TData>() where TData: struct
{
return things.OfType<TData>().ToArray<TData>();
}
I'm still curious about any penalties for .ToArray() because this is data which will be sent to a stream object, and there could be a lot of it.
It seems to me that a few LINQ queries will suffice.
//getting only ThingA from mixed array
IEnumerable<ThingA> thingsA = things.OfType<ThingsA>()
//we know type of thins inside array, so we just need type conversion
IEnumerable<ThingB> thingsB = things.Cast<ThingB>()
Don't use Convert, it's for real conversion (e.g, string to int), and what you have is type casting.
ChangeType method signature exposes two parameters, the first: value must be an object which implements IConvertible interface. In your example things is an object array and doesn't implement that interface.
You should design your GetArrayOfThings method in a different way like this:
public TData[] GetArrayofThings() where TObject:IConvertible, TData: struct

Producing an abstract collection from an abstract collection

This issue has been bugging me for a while. Abstractly speaking, regardless of language, there are often situations when you want to have a method like this:
Collection method(Collection c) {
// select some elements from c based on some filter
// and return a new collection
}
Now, Collection is in this case some abstract class (Like say IList in C# or List in Java) with several implementations. I've been wondering what exactly is the right procedure to produce the abstract collection?
Is it ok to create a concrete collection inside the method and return it? Like:
Collection method(Collection c) {
Collection cc = new ConcreteCollection();
// select some elements from c based on some filter
return cc;
}
This of course puts a constraint on the resulting collection and will produce problems in case, for some reason, we want to cast the result of the method to a different concrete collection than the one used inside the method.
Or, use reflection to determine the actual concrete type of c and create an instance of that class:
Collection method(Collection c) {
Collection cc = c.getClass().newInstance();
// select some elements from c based on some filter
return cc;
}
For some reason this does not seem very "elegant" to me. I would greatly appreciate some insight in this matter.
(Speaking for java). The reason you're returning Collection (an interface) rather than a concrete type (such as ArrayList) is that you're telling the user that they shouldn't care about what the actual concrete type being used is. This leaves you free to choose the appropriate type for your library/api.
If you're enforcing a particular concrete class, then you should be returning that concrete class, rather than the interface.
So, they shouldn't be casting your return type to anything else other than Collection. See
When should I return the Interface and when the concrete class?.
In Java, there are actually some good examples of how to do this in the java.util.Collections class. Instead of taking a Collection and returning a Collection, the key methods take two collections, the "src" and the "dest". For example, Look at the signature of the copy method:
public static <T> void copy(List<? super T> dest, List<? extends T> src)
This puts the responsibility of instantiating the destination list on the caller.
I think you could do the same thing when you want to create a method that acts on a src Collection and puts the results into a destination Collection (rather than Lists).
I agree with Matthew Farwell's answer that you probably just want to return the interface and utilize that, but for the times when you really do need to work with a specific implementing class you can do it the same way the Collections class does it.
One approach you could take is to create a Collection implementation that delegates calls through to the original Collection. This defers the potentially expensive operation of filtering a large Collection until you need to explicitly read elements. It also saves memory.
Example
public interface Filter<T> {
boolean include(T t);
}
public class FilterCollection<T> implements Collection<T> {
private final Collection<T> orig;
private final Filter<T> filter;
public FilterCollection(Collection<T> orig, Filter<T> filter) {
this.orig = orig;
this.filter = filter;
}
public int size() {
int sz = 0;
for (T t : orig) {
if (filter.include(t)) {
++sz;
}
}
return sz;
}
public boolean contains(Object o) {
return o instanceof T && filter.include((T) o) && orig.contains(o);
}
public boolean add(T t) {
if (!filter.include(t)) {
throw new IllegalArgumentException("Element lies outside filter bounds.");
}
orig.add(t);
}
}
The caller should assume a given type of Collection is returned.
Instead it should either copy to the desired type or pass the desired type.
e.g.
Set<T> set2 = new HashSet<T>(filter(set));
List<T> list2 = new ArrayList<T>(filter(list));
or
filter(set2, set); // the target collection is passed.
filter(list2, list);
To the question about ConcreteCollection, it is definitely allowable.
To the concern about having a different concrete collection expected, there are a few ways to go around the problem:
Change the return type of the method. Example:
ConcreteCollection method(Collection c){
ConcreteCollection cc=new ConcreteCollection
for(Object x: c){
//do something
}
return cc
}
Make use of polymorphism. Example:
Collection x=method(c)
x.add(new Object) //add is a method defined within the abstract Collection
Use some utilities to cast the type. Example:
LinkedList h=Collections.toLinkedList(method(c))
Hoped my answer helped. ^^
As far as I can understand, you want to know how to make a method that accepts generic list and returns another modified generic list.
So, my advice will be to use an abstract type that implements method to modify its state.
IList<object> list = new List<object>();
list.Add(new object());
list.Remove(obj);
Or as showed above, instantiate a list that implements IList (or the Java equivalent) work with this instance and return the result as a IList
Edit
If you want to filter some item from a list to a new one, generics can help (I don't know if this feature exists in Java).
public IList<T> Filter<T>(IList<T> list)
{
var result = new List<T>();
result.Add(list[0]); // Or whatever filtering method
return result;
}
If you want your method to accept as many different collection types as possible, and you want to be sure that the result is the same implementation type as what you put in, you might want to use a void method which directly modifies the supplied collection. For instance:
import com.google.common.base.Predicate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class Testy {
private static <T> void filter(Iterable<T> collection, Predicate<T> filter) {
Iterator<T> iterator = collection.iterator();
while (iterator.hasNext()) {
if (!filter.apply(iterator.next())) { // Condition goes here
iterator.remove();
}
}
}
public static void main(String... args) {
List<String> list = new ArrayList<String>();
list.addAll(Arrays.asList("A", "B", "C", "D"));
filter(list, new Predicate<String>() { // Anonymous filter (predicate)
#Override public boolean apply(String input) {
return input.equals("B");
}
});
System.out.println(list); // Prints ["B"]
}
}
The helper method filter takes an Iterable, the simplest type required for iterating over something. Apply the filter to each element, and if the predicate (filter) returns false, remove that element from the underlying collection with Iterator.remove().
The Predicate<T> interface here comes from Google. You can easily write your own if you don't wish to import it. The only required method is apply(T) which returns a boolean. Either that, or just write your condition directly inside the loop and get rid of the second parameter.
This method is the most efficient if your original collection is mutable and you don't wish to keep any intermediate results.
Another option is to use Google Collections Collections2.filter(Collection<E>, Predicate<E>) which returns a Collection<E> just like in your question. Similarly, the Iterables class will do the same thing, but create lazy iterables where the filters are only applied when actually doing the iterating.

Casting generic object array to two types

I've got a method that receives an Object[] and then performs actions on that array.
At first I was passing in this array as an IEnumerable<T> however the T can be of two different types.
The T's will always have the same properties, even thought they're different types.
Is it possible to cast to a a type at runtime so that I can used the properties i know each one will contain?
So where as it's possible to do:
var dataObject = (IEnumerable<T>) dataArray;
Is it somehow possible to do:
var dataObject = (dataArray.GetType()) dataArray;
Are you able to modify the source code of the two T types? If so then you could make both of them either (a) inherit from a common base class or (b) implement a common interface.
Edit following comments...
To accomodate different types for the ID property you could use explicit interface implementation. This would allow you to expose the second object's ID as an Int64 when accessed via the common interface. (The ID property would remain accessible as an Int32 when not accessed through the interface.)
Unfortunately the explicit interface implementation will require more changes to your original types.
void YourMethod(IEnumerable<ICommonToBothTypes> sequence)
{
foreach (var item in sequence)
{
Console.WriteLine(item.ID);
}
}
// ...
public interface ICommonToBothTypes
{
long ID { get; }
}
public class FirstType : ICommonToBothTypes
{
public long ID
{
get { return long.MaxValue; }
}
}
public class SecondType : ICommonToBothTypes
{
// the real Int32 ID
public int ID
{
get { return int.MaxValue; }
}
// explicit interface implementation to expose ID as an Int64
long ICommonToBothTypes.ID
{
get { return (long)ID; }
}
}
You can just create it as an interface and have both of those classes implement the interface. Then take Interface[] as the parameter instead of Object and you avoid casting all together.
If the two objects in the array derive from the same base type (inheritance) then you can box all the objects in your array as base class objects and you can use them with no knowledge of which particular object it might be.
See here for Boxing and Unboxing information from Microsoft
This is in essence what polymorphism is about, handling objects with a common interface.
Either inheritance from the same base class or creating an interface that both objects support will suit in this case. You will then be able to specifically define your array with either the base class type or the interface type, rather than "object".
If it's impossible to have the different classes all inherit the same interface, you can get all the properties defined in an object as a collection and then their value through key lookup where the key is the name of the property. I'd implement this as extension methods like so:
public static Dictionary<string, object> GetProperties<T>(this T instance)
where T : class
{
var values = new Dictionary<string, object>();
var properties =
instance.GetType().GetProperties(BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.GetProperty);
foreach (var property in properties)
{
var accessors = property.GetAccessors();
if ((accessors == null) || (accessors.Length == 0))
continue;
string key = property.Name;
object value = property.GetValue(instance, null);
values.Add(key, value);
}
return values;
}
Then you can just do like this to get the property values:
void DoStuff(object[] objects)
{
foreach (var o in objects)
{
var properties = o.GetProperties();
var value = properties["PropertyName"];
}
}
It will all be untyped and you'll break things when renaming properties if you forget to also rename the lookup keys in the consuming code, but otherwise, this should work fine. However, the best solution is undoubtedly the one suggested by Luke (using interfaces).
If you have access to the sourcecode defining the two element types
You should introduce a new interace containing the common properties and let the other two interfaces inherit from your new base interface.
In your method you then use IEnumerable.Cast(TResult) to cast all elements to the common interface:
var dataObject = dataArray as IEnumerable;
if (dataObject != null)
{
var data = dataObject.Cast<ICommonBase>()
// do something with data
}
If you can't modify the sourcecode defining the two element types:
Use the IEnumerable.OfType() to filter elements based on their known types, effectively creating two strongly typed collections. Next perform the same operations with each of them (most verbose approach).
var dataObject = dataArray as IEnumerable;
if (dataObject != null)
{
var a = dataObject.OfType<InterfaceA>()
// do something with a
var b = dataObject.OfType<InterfaceB>()
// do the same with b
}
A reference of the functions used can be found on msdn.
If you want to avoid code duplication your only chance will be to use something called duck typing.Phil Haack has a great article on it.
The idea is to introduce a new interface that contains the common elements. You then duck-type the array elements, effectively making them comply to the new interface at runtime.
The last option would be using reflection and extracting property infos by common names and then access each elements data. This is the slowest and IMHO most cumbersome approach.

Categories