Due to a recent issue i had some days ago (you can check this post here), i needed to create a way that some of my linq to sql tables could be referenced dynamically. I've managed to do that through an abstract LogTable class, which contains all my LogTable properties as defined on my DataTable. I was able to do this abstract way because my LogTables have the same structure, thus the same properties.
Heres the reducted code:
Abstract base class
public abstract class LogTableStructure
{
public int ID { get; set; }
public datetime? LastAccess { get; set; }
public string Username { get; set; }
}
My (reducted) dynamic method to update a LogTable:
public void UpdateLog<T>(T currentLOG) where T : LogTableStructure
{
LogTableStructure logStructure = null;
//LogTableEnum is defined on this class constructor
switch (LogTableEnum)
{
case LogTableEnum.Log2009:
logStructure = this.factory.LogDB.LOG_2009s
.SingleOrDefault(q => q.ID == currentLOG.ID);
break;
case LogTableEnum.Log2010:
logStructure = this.factory.LogDB.LOG_2010s
.SingleOrDefault(q => q.ID == currentLOG.ID);
break;
case LogTableEnum.Log2011:
logStructure = this.factory.LogDB.LOG_2011s
.SingleOrDefault(q => q.ID == currentLOG.ID);
break;
}
}
PROBLEM
for some reason the currentLOG param throws a runtime null reference exception, even though it has all LogTable properties filled. I've notice by using vs2010 debbuger that while the currentLOG properties are filled, the base class (LogTableStructure) properties are all empty, as if the base object is null.
Am i forgeting something about member hide inheritance or something alike? I've even added the new modifier to all my LogTable properties on my .dbml, but even that didn't solve the problem
Just make the object into which you're injecting an actual instance:
// This object is going to have to be a class that inherits from your abstract class
// It can't be a null object of the type of your abstract class.
var logStructure = new InstanceOfLogTableStructure();
logStructure.InjectFrom(currentLOG);
That should do it.
You seem to have your ordering wrong. You're assigning null to logStructure, then you're calling InjectFrom on it. Only then are you assigning a factory-created instance to that variable.
Related
I want to compare 2 objects like below :
I don't want 2 employees in the same department
I don't want 2 Animals in the same Zoo
So on.....
I am trying to implement IEqualityComparer to accept generic type argument to take Employee or Animals or any object and to the comparison for me but I ran into a problem because since I have T as an argument, I am not getting the properties on T.
public class GenericComparer<T> : IEqualityComparer<T>
{
public bool Equals(T x, T y)
{
// Not getting a property here T.??
//now if I would have T as an Employee then I could do something like this here:
// return String.Equals(x.Name, y.Name); // but this will work because I know that Name is string
// but lets say if I have a different datatype that I want to compare then how can i do that?
}
public int GetHashCode(T obj)
{
return obj.
}
}
The thing is I don't want to create 2 classes like EmployeeComparer: IEqualityComparer<Employee> and AnimalComparer : IEqualityComparer<Animal> as the code will be somewhat similar.
Is it possible to create generic compared to compare any objects of the same types?
Update:
I am just trying to understand the limitations of generics with reference types. When should we create a Generic class or methods to accept reference types and when we should not.
I was thinking that since List<T> can accept anything like List<Employee> or List<Animal> or anything then why my GenericComparer cannot.
Because when we create List<Employee> then we can run for each loop and access the properties right:
foreach(var employee in employees)
{
string name = employee.Name; //Here we are able to access the properties
}
Then how come not in my case?
Answer to all the above questions will help me understand generics better with reference type especially. So, if someone can provide an answer to all this question and why it is not possible with my GenericComaprer<T> and how it is possible with List<T> then I will really appreciate :)
when we create List<Employee> then we can run for each loop and access the properties
Sure, because you are using List<T> by providing it the concrete type (Employee) to use in place for T. But if you were to look at the internals of (or try to write your own version of) List<T> you'd see you have no way to access an hypothetical Name property of T. That is because C# is a strictly typed language (contrarily to Javascript or Python for example). It won't let you use anything it doesn't know beforehand and for sure exists.
The way you defined your GenericComparer<T> class, all the compiler know is that T can do what every C# objects can, that is... not much (you can use ToString() and GetType() and compare references, that's pretty much all).
Then, because otherwise generics wouldn't be very useful, you can specify constraints on your generic type: you can, for example, tell the compiler that T must implement some interface. If you do this, then you can access any member defined in this interface on your T instances from inside the generic class.
For the sake of the example, let's say you have employees and animals; both employees and animals have a Name, then employees also have a Salary but animals have a Species. This could look like this:
public class Employee {
public string Name { get; set; }
public double Salary { get; set; }
}
public class Animal {
public string Name { get; set; }
public string Species { get; set; }
}
If we keep it that way, as explained above, you won't be able to access the properties from your generic class. So let's introduce an interface:
public interface IHasName {
string Name { get; }
}
And add : IHasName at the end of the Employee and Animal class declarations.
We also need to tweak GenericComparer declaration this way:
public class GenericComparer<T> : IEqualityComparer<T> where T : IHasName
By doing this, we tell the compiler that the T in GenericComparer must implement IHasName. The benefit is now you can access the Name property from within GenericComparer. On the other side, you won't be able to use GenericComparer by passing it anything that doesn't implement IHasName. Also note that the interface only defines the ability to get the Name property, not to set it. So, although you can of course set the Name on Employee and Animal instances, you won't be able to do so from inside GenericComparer.
With the definitions above, here is an example of how you could write the GenericComparer<T>.Equals method:
public bool Equals(T x, T y)
{
// Just a convention: if any of x or y is null, let's say they are not equal
if (x == null || y == null) return false;
// Another convention: let's say an animal and an employee cannot be equal
// even if they have the same name
if (x.GetType() != y.GetType()) return false;
// And now if 2 employees or animals have the same name, we'll say they are equal
if (x.Name == y.Name) return true;
return false;
}
All that said, I don't know exactly what your use case for GenericComparer<T> is (maybe you need this in a Dictionary or some other method that requires a way to compare instances... Anyway, as other commenters have stated, the proper way to go would probably be to:
override Equals and GetHashCode
provide == and != operators
implement IEquatable<T>
Do this on all classes you want to have a custom implementation of equality.
If you happen to use a recent version of Visual Studio (I'm using VS 2019 16.8 at the moment), you can automatically do all of this by right-clicking the class name, choosing Quick Actions and Refactorings > Generate Equals and GetHashCode. You will be presented with a window that allows you to choose the properties that should be part of the equality logic and you can also optionally choose to implement IEquatable<T> and generate == and !=. Once done, I'd recommend you review the generated code and make sure you understand what it does.
By the way, if you do so, you'll notice that the generated code uses EqualityComparer<Employee>.Default. This is pretty much what you tried to implement by yourself with your GenericEqualityComparer.
Now to the part of your questions relating to reference types. I'm not sure I understand your questions for I don't see an obvious link between generic types and references. Generic types can act just as well on both reference and value types.
What bothers you is maybe the fact that equality does not work the same way in reference and value types:
For reference types, the default way the compiler considers things equal is to look at their references. If the references are the same, then the things are considered the same. To put it differently suppose you create 2 instances of an Employe class and feed them with exactly the same Name and Salary. Because they are distinct objects (with distinct places in memory, that is different references), emp1 == emp2 will return false.
In the case of value types (suppose Employee is a struct and not anymore a class), the compiler does something else: it compares all the properties of the struct and decides based upon their content whether the 2 employees are equal or not. In this case, emp1 == emp2 will return true. Note that here, the compiler (or rather the .NET runtime) is doing something similar to what you attempt to do with your universal comparer. However, it only does so for value types and it is rather slow (this is why one should often implement IEquatable and override Equals and GetHashcode on structures).
Well, I'm not sure I've answered all your questions, but if you want to know more, you should definitely go through some C# tutorials or documentation to understand more about reference vs value types and equality (even before you jump into implementing your own generic types).
What you're expecting of generics just isn't right:
I was thinking that since List<T> can accept anything like List<Employee> or List<Animal> or anything then why my GenericComparer cannot.
foreach(var employee in employees)
{
string name = employee.Name; //Here we are able to access the properties
}
Here you say that you can access the properties, but that's specifically because the list employees was instantiated as List<Employee>. The implementation of List however could Not access those properties, because it only sees T !
There are some ways to achieve what you want, but you'd have to consider design and performance pros/cons depending on your specific use-case and needs.
Here's what you could do:
public abstract class CustomComparable
{
// Force implementation to provide a comparison value
public abstract object GetComparisonValue();
}
public class Employee: CustomComparable
{
public int Department { get; set; }
public override object GetComparisonValue()
{
return Department;
}
}
public class Animal : CustomComparable
{
public string Zoo { get; set; }
public override object GetComparisonValue()
{
return Zoo;
}
}
public class CustomComparer<T> : IEqualityComparer<T> where T: CustomComparable
{
public bool Equals(T x, T y)
{
return x != null && y != null && x.GetComparisonValue().Equals(y.GetComparisonValue());
}
public int GetHashCode(T obj)
{
return obj.GetComparisonValue().GetHashCode();
}
}
Then you'd get this, for example:
class Program
{
static void Main(string[] args)
{
Animal cat = new Animal() { Zoo = "cat zoo" };
Animal dog = new Animal() { Zoo = "dog zoo" };
Animal puppy = new Animal() { Zoo = "dog zoo" };
List<Animal> animals = new List<Animal>() { cat, dog, puppy };
CustomComparer<Animal> animalComparer = new CustomComparer<Animal>();
Console.WriteLine($"Distinct zoos ? {animals.Distinct(animalComparer).Count() == animals.Count}");
Employee bob = new Employee() { Department = 1 };
Employee janet = new Employee() { Department = 2 };
Employee paul = new Employee() { Department = 3 };
List<Employee> employees = new List<Employee>() { bob, janet, paul };
CustomComparer<Employee> employeeComparer = new CustomComparer<Employee>();
Console.WriteLine($"Distinct departments ? {employees.Distinct(employeeComparer).Count() == employees.Count}");
}
}
> Distinct zoos ? False
> Distinct departments ? True
With all that being said, do use IEquatable<T>. The specific use of such equality implementations seems out of the scope of your initial question however, and many other resources and Q&A's can help you with these.
What you describe is easily possible, just use delegates.
public class GenericComparer<T, TValue> : IEqualityComparer<T>
{
private Func<T, TValue> _getter;
private IEqualityComparer<TValue> _valueComparer;
public GenericComparer(Func<T, TValue> getter, IEqualityComparer<TValue> valueComparer = null)
{
_getter = getter;
_valueComparer = valueComparer ?? EqualityComparer<TValue>.Default;
}
public bool Equals(T x, T y)
{
return _valueComparer.Equals(_getter(x), _getter(y));
}
public int GetHashCode(T obj)
{
return _valueComparer.GetHashCode(_getter(obj));
}
}
To use it, simply tell it by which property you want it to compare:
var animalByNameComparer = new GenericComparer<Animal, string>(an => an?.Name);
Of course, you can also handle the null case already in the generic comparer, also.
To your second question
The simple difference between List<T> and List<Employee> is that the former is an open generic type while the latter is a closed generic type. If you define a generic type, you always define it as an open generic type, so the compiler does not know what T will be. If you consume a generic type, you often work with closed generic types, i.e. the placeholder T already has a value and therefore, the compiler is able to resolve a symbolic name like .Name to a property. If you use the generic type in an open generic method (a method with a type parameter), you also cannot bind symbols.
I am getting a runtime exception and can't figure out why
Unable to cast object of type
'System.Collections.Generic.List`1[Foo.ElementNameViewModel]'
to type
'Foo.ElementNameList'.
The classes I have are
ElementNameList - a list of a particular type
namespace Foo
{
public class ElementNameList : List<ElementNameViewModel> {}
}
ElementNameViewModel - an item to be in a list
namespace Foo
{
public class ElementNameViewModel
{
public string Symbol { get; set; }
public string Name { get; set; }
}
}
and the exception occurs in a controller at
var elements = (ElementNameList) db.Elements
.Select(c => new ElementNameViewModel
{
Symbol = c.Symbol,
Name = c.Name
})
.OrderBy(e => e.Symbol)
.ToList();
Not sure how I should refactor the elements list if subclassing List is not done.
ToList() returns a real System.Collections.Generic.List instance, not your ElementNameList.
You can cast ElementNameList to IList<ElementNameViewModel> or to List<ElementNameViewModel>, but not the other way.
The reason is because your ElementNameList may have a property that the List<ElementNameViewModel> doesn't have. What would happen if you try to access that property after the cast?
public class ElementNameList : List<ElementNameViewModel> {
public int X { get; set; }
}
var list = new List<ElementNameViewModel>();
ElementNameList elementList = (ElementNameList) list;
int x = elementList.X; // List<ElementNameViewModel> doesn't have 'X' property, what would happen here?
As said in other answers like Optimistic Peachs' and lmcarreiro's one, the ToList() LINQ extension method returns an
basic List<T> object, not an object of your customized ElementNameList class.
To solve your immediate problem, I would write it as:
var qry = db.Elements
.Select(c => new ElementNameViewModel
{
Symbol = c.Symbol,
Name = c.Name
})
.OrderBy(e => e.Symbol);
var elements = new ElementNameList();
elements.AddRange(qry);
I don't have an Visual Studio at hand now to see if I need to
use qry.ToList() in the AddRange call, but I believe that
is enough.
By the way, why you had to subclass the list?
Casting to inherited/derived members only goes one way... And that is up the derived hierarchy.
For example:
class Animal{
int number_of_legs;
}
class Cat: Animal{
string current_sound = "meow";
}
If you create an animal (Which should really be abstract in this case, but ignore that) and want to convert it into a cat, and assign that to a variable mycat then what would the value stored in mycat.current_sound be? It cannot be inferred because Cat has all the members that Animal has and more, so the conversion from Cat to Animal would make you lose the members that Cat has and only be left with the members from Animal (Unless you cast it again but that's irrelevant...)
P.S. I've recently been coding in a different language so pardon my naming of variables and format of my code
I am trying to reduce code from the data layer (Class Library) of a project by making a generic DAO class with virtual methods, this way I will have implementations of this class for the various types needed.
For simplicity's sake I will only write the read method for all classes and only the necessary parameters.
One requirement is the object used as return for all methods within this layer, which is a generic class as below:
public class ReturnObject<T>
{
public T Object { get; set; }
}
I started with an interface IDao:
public interface IDao<T>
{
ReturnObject<T> Read(Guid id);
}
And then, the "default implementation":
public abstract class Dao<T> : IDao<T>
{
// Database context.
protected Context Context { get; } = new Context();
public virtual ReturnObject<T> Read(Guid id)
{
// Creating return object.
var returnObject = new ReturnObject<dynamic>();
// Reading entity from database.
try
{
switch (typeof(T).ToString())
{
case "Foo":
returnObject.Object = Context.Foos.First(o => o.Id == id) as dynamic;
break;
case "Bar":
returnObject.Object = Context.Bars.First(o => o.Id == id) as dynamic;
break;
}
}
catch (Exception exception)
{
...
}
finally
{
...
}
// Returning result.
return returnObject as ReturnObject<T>;
}
}
So, basically this is the code reduction I'm trying to get. Based on the T class type I will be able to switch the proper set from the context, store the read object into the returnObject and then send it back to the caller.
For organization and other reasons, I also have several inherited classes, like this:
public class DaoFoo : Dao<Foo>
{
}
And finally, my problem. I'm positive I'm misinterpreting some concepts here and that's why I'm getting null values when calling the method read as exampled below:
public class FooController : ApiController
{
public IHttpActionResult Get(Guid id)
{
var foo= new DaoFoo().Read(id);
return Content(HttpStatusCode.OK, new foo.Object);
}
}
When debugging I can see that the Dao class is sending the right object, with all its parameters, like in the image:
However, the calling method always gets null, like in the image:
With all that said, can someone point out what I'm doing wrong here?
Thanks in advance!
You cast dynamic as ReturnObject which results in null, because it cannot cast one type to another.
Try not using dynamic, your method is generic so use T instead, so you dont have to cast
returnObject is a ReturnObject<object>, but returnObject as ReturnObject<T> is null. The as operator will return null if the provided value isn't of the specified type.
I'm trying to learn AutoFixture, and I've got xUnit and NSubstitute and AutoFixture setup to automatically mock out properties with fakes (with AutoFixture.AutoNSubstitute). In other words, if I have the following interface
public interface IFoo
{
IBar1 Bar1 {get;}
IBar2 Bar2 {get; set;}
}
Trying to resolve an IFoo will automatically resolve and populate Bar1 and Bar2.
Everything works great for objects with properties of interface, concrete object, or structure types. I'm having a problem getting AutoFixture to automatically create properties of abstract types however.
I have tried using a TypeRelay for the abstract type, so
fixture.Customizations.Add(new TypeRelay(typeof (AbstractBase), typeof (ConcreteChild)));
I have tried specifying it this way,
fixture.Customize<AbstractBase>(
composer =>
composer.FromFactory(
(string ChildParam1, string ChildParam2) => new ConcreteChild(ConcreteChildParam1, ConcreteChildParam2)));
I have tried using various custom specimen builders
Resolving via the property type:
var pi = request as PropertyInfo;
if (pi != null &&
pi.PropertyType == typeof(AbstractBase))
return context.Resolve(typeof(ConcreteChild));
return new NoSpecimen(request);
Resolving via the class type:
var pi = request as Type;
if (pi != null &&
pi == typeof (AbstractBase))
return context.Resolve(typeof(ConcreteChild));
return new NoSpecimen(request);
With both of the above solutions, I also tried context.Create<ConcreteChild>()
Finally I have tried using the Register<AbstractBase>(fixture.Create<ConcreteChild>); syntax.
None of them seem to work as far as automatically populating properties on an object.
The irritating thing is that I can explicitly fixture.Create<AbstractBase>(); in an individual test and get the ConcreteChild and then hand-jam everything but that kind of defeats the purpose of AutoFixture no?
Any ideas?
UPDATE:
The abstract class. I've pruned most of the irrelivent stuff, left the ctor code in as I'm assuming it gets called?
public abstract class ChatEntityId
{
private string _localName;
protected ChatEntityId(string chatRoomName, string entityUid, ChatProtocol protocol)
{
ErrorChecker.NormalizeToNullIfNotSet(ref chatRoomName);
ErrorChecker.NormalizeToNullIfNotSet(ref entityUid);
if (chatRoomName == null && entityUid == null)
{
throw new ArgumentException("Both chatRoomName and entityUid may not be null at the same time.");
}
ChatRoomName = chatRoomName;
EntityUid = entityUid;
Protocol = protocol;
}
public string ChatRoomName { get; private set; }
public string EntityUid { get; private set; }
public bool Equals(ChatEntityId chatEntityId) { }
public override bool Equals(object obj) { }
public override int GetHashCode() {}
public string LocalName { get; }
public ChatProtocol Protocol { get; private set; }
public override string ToString() { }
}
ChatProtocol is an enum, fairly standard.
The AutoPopulatedProperty ICustomization
public virtual void Customize(IFixture fixture)
{
fixture.Customize(new DomainCustomization());
// Replacement for the AutoNSubstituteCustomization, this Postprocessor will automatically create fake objects on properties.
fixture.ResidueCollectors.Add(
new Postprocessor(
new NSubstituteBuilder(
new MethodInvoker(
new NSubstituteMethodQuery())),
new AutoPropertiesCommand(
new PropertiesOnlySpecification())));
}
private class PropertiesOnlySpecification : IRequestSpecification
{
public bool IsSatisfiedBy(object request)
{
return request is PropertyInfo;
}
}
Somewhat embarrassingly, I realized that NSubstitute has what it calls recursive mocking, which is partially what I want and explains why I couldn't figure out where some of the auto-mocked properties were coming from. The problem is that it doesn't do it across the board (probably rightfully so), and isn't really extensible in that regard as far as I can tell.
Now AutoFixture comes into play, after we create the specimen in the Postprocessors NSubstituteBuilder, the AutoPropertiesCommand class is called and fetches what it determines are the appropriate properties to populate with data.
Unfortunately none of the logic in the two relevant classes (there is a non-generic inheriting from a generic AutoPropertiesCommand class) is overridable and this is where the problem occurs. Specifically, AutoPropertiesCommand<T> has two methods it uses to get properties and fields, which it then filters using the supplied IRequestSpecification (PropertiesOnlySpecification in this case).
The method in question
private IEnumerable<PropertyInfo> GetProperties(object specimen)
{
return from pi in this.GetSpecimenType(specimen).GetProperties(BindingFlags.Public | BindingFlags.Instance)
where pi.GetSetMethod() != null
&& pi.GetIndexParameters().Length == 0
&& this.specification.IsSatisfiedBy(pi)
select pi;
}
So the solution here is to either provide my own AutoPropertiesCommand implementation without the above limitations or explicitly create customizations for each case I run across. Haven't decided which approach I like better but probably the former.
As a side-bar it seems kind of restrictive to not have those two methods as protected virtual, is there any particular reason for this beyond "it was just coded that way"? Those are base AutoFixture classes I believe, for the record.
I have a couple of objects that have a corresponding object with identical properties.
class Source1
{
int id;
string name;
DateTime date;
}
class Destination1
{
int id;
string name;
DateTime date;
}
class Source2
{
int id;
string code;
double price;
}
class Destination2
{
int id;
string code;
double price;
}
Now I want to make a method with generic types that can cast an object into his corresponding object.
public TDestination Cast<TSource, TDestination>(TSource source)
{
//TDestination destination = (TDestination) source;
return destination;
}
Your best option here is to introduce a common interface (or base class). There is no other way to cast an item into another.
public interface IItem
{
int id {get;set;}
string name {get;set;}
DateTime date {get;set;}
}
class Source1 : IItem
{
public int id {get;set;}
public string name {get;set;}
public DateTime date {get;set;}
}
class Destination1 : IItem
{
public int id {get;set;}
public string name {get;set;}
public DateTime date {get;set;}
}
You can then just cast the object into the interface and access the properties.
var item1 = (IItem)sourceItem;
var item2 = (IItem)destinationItem;
If you don't want to do that another option would be to using reflection go trough the properties in the source and create a new object of the destination type and try to map properties with shared names. This would however create a new object and is not the same at all as casting. There are libraries such as AutoMapper that can help you with this.
AutoMapper.Mapper.CreateMap<Source1, Destination1>();
var destItem = AutoMapper.Mapper.Map<Destination1 >(sourceItem);
As Magnus points out, if you want to actually cast, interfaces are your way to go. However, I'm thinking you might be actually looking at converting rather then casting.
I would consider checking Automapper as it exists for exactly that.
From the documentation:
var source = new Source<int> { Value = 10 };
var dest = mapper.Map<Source<int>, Destination<int>>(source);
dest.Value.ShouldEqual(10);
You can configure mappings between two types by either naming conventions (even custom naming conventions), custom mappers or a combination of both. The most common use case I have seen for this is mapping a datatransfer object to a model and back again.
If one object is basically the other object with some extra logic and properties the Decorator pattern might be what you are looking for. Here you basically wrap (decorate) one object with some extra stuff and the decorating object links everything through to the original object.
Boris Calens pointed out Automapper, which is great, but if you want to avoid using outside code, a home-made solution for your example problem is pretty simple:
using System.Reflection;
...
TDestination Copy<TSource, TDestination>(TSource source)
where TDestination : new()
{
TDestination dest = new TDestination();
foreach (FieldInfo srcField in typeof(TSource).GetFields())
{
foreach (FieldInfo destField in typeof(TDestination).GetFields())
{
if (destField.Name == srcField.Name && destField.FieldType == srcField.FieldType)
{
destField.SetValue(dest, srcField.GetValue(source));
}
}
}
return dest;
}
You could also easily loop through the properties of the respective types; specify binding flags to filter which fields/properties get copied; and expand the comparison for determining whether the two members are of the same type (i.e. checking whether one type is derived from another).
My answer to this question (which you may also find helpful) shows a similar example, comparing properties and fields.