there are many questions arround about this theme, but I didn't find one, which answers my question:
I'm toying arround with the MVVM. In order to give the views a possibility to request a ViewModel-switch, I implemented a Event in the abstract base class.
My method to switch looking like this:
private void ChangeCurrentView(Type viewType, IEnumerable<Object> constructorArguments)
{
if (_currentContent != null)
{
_currentContent.ChangeViewRequested -= view_ChangeViewRequested;
}
ViewModelBase vm;
if (constructorArguments == null)
{
vm = (ViewModelBase)Activator.CreateInstance(viewType);
}
else
{
vm = (ViewModelBase)Activator.CreateInstance(viewType, constructorArguments);
}
vm.ChangeViewRequested += view_ChangeViewRequested;
_currentContent = vm;
OnPropertyChanged("CurrentContent");
}
My problem lies in the CreateInstance: As you can see I have to check if the arguments are null and if so, I use the method without arguments. But even if the arguments are filled, for example:
public QuestionViewModel(Question question)
and the constructorArgument has just 1 object of this type, it doesn't seem to handle this proper.
is there a possibility to get this dynamic creating work, or are there other ways to make this anyhow happen?
Thanks as usual and a good start in the week.
Matthias
Edit: The error I get is "The constructor for the type "MMU.QuestionHelper.GUI.ViewModel.QuestionViewModel" was not found."
I translated it myself, because my VS is in german.
Related
Please help me with this question. I'm coding come ability system in Unity3D 2019.4.1 (if you might want to know) and have had created "Roller" class for some random numbers. There is
public static Func<Creature, int> OnNumberRolled;
in "Roller" class. Some of abilities in my game must know about these random numbers and when they are rolled, they invoke some mess.
Here is an ability class:
public class ListenerEffect : Effect
{
public int OnRolledOne(Creature creature)
{
...
}
public override void CastEffect(ITargetable caster, ITargetable target)
{
Creature localCasterCreature = caster as Creature;
Roller.OnNumberRolled += OnRolledOne(localTargetCreature);
}
}
At this moment
Roller.OnNumberRolled += OnRolledOne(localTargetCreature);
error occurs. It says that it can't convert "int" into "System.Func<Creature, int>". Both classes are using System. What should I do?
Just use the name of the function. Otherwise, you are calling the function and are using the returned value.
Roller.OnNumberRolled += OnRolledOne;
If you add several handlers, keep in mind that the return values will be lost (but the last one) on invocation as OnNumberRolled().
You might have the handlers to add their results to a list or something like that, but we would need more insight on your use cases to design a satisfactory solution.
You can also iterate on handlers like this:
var handlers = OnNumberRolled.GetInvocationList();
foreach (var handler in handlers)
{
// invoke and handle each handlers'result here
Debug.Log(handler());
}
I have a C# class which contains the following:
public event Action<int> UnsupportedMessage;
It also has a method containing
if (template != null)
{
...
}
else
{
if (UnsupportedMessage != null)
{
UnsupportedMessage(templateId);
}
}
Another C# class called HealthCheck contains public void MyMessage(int id).
What's supposed to happen is if template is null, an event should call HealthCheck.MyMessage().
So many things are wrong here. UnsupportedMessage is always null so UnsupportedMessage(templateId); never gets executed. Even is I remove if (UnsupportedMessage != null) UnsupportedMessage(templateId); will throw System.NullReferenceException: 'Object reference not set to an instance of an object.'. Even if it did work, there's no reference to HealthCheck.MyMessage() so I don;t know how it could ever be run.
How do I create an event to do what I need?
Update
I tried changing to UnsupportedMessage?.Invoke(templateId); as mentioned in the below answer and added this in the line above it:
UnsupportedMessage += _handlerClass.UnsupportedMessage;
_handlerClass is initialized by the constructor contains this method:
public void UnsupportedMessage(int value)
{
...
}
This initially seemed to work but it seems to be getting called many more times than I expected.
It sounds like you're simply missing the event subscription step; you'd presumably need:
objectThatIsGoingToRaiseTheEvent.UnsupportedMessage += healthCheckInstance.MyMessage;
which will make UnsupportedMessage become non-null, and make everything work. You should also change:
if (UnsupportedMessage != null)
{
UnsupportedMessage(templateId);
}
to either
UnsupportedMessage?.Invoke(templateId);
or (on older C# versions, noting that this is semantically identical)
var handler = UnsupportedMessage;
if (handler != null) { handler(templateId); }
to avoid a race condition that is possible if the last event-handler unsubscribes (-=) between the two reads of UnsupportedMessage in the original version.
This is a method for recursively searching through a binary tree that is filled with objects of the various child classes of the class Photo.
public void SearchForIdentical(Photo searched)
{
SearchForIdentical(ref root, searched);
}
void SearchForIdentical(ref TreeNode current, Photo searched)
{
try
{
if(current != null)
{
if(current.content.Equals(searched))
{
throw new PhotoAlreadyExistsException(searched);
}
SearchForIdentical(ref current.left, searched);
SearchForIdentical(ref current.right, searched);
}
}
catch (PhotoAlreadyExistsException e)
{
Console.WriteLine("This photo already exists! Try a new one!");
}
}
A 'photo' is defined by the value of its various arguments and properties (the child classes don't necessarily all have the same kind of arguments and properties). If the user types in a new photo, that is fully identical in all its arguments and properties with an existing one, this method should notice it, and throw an exception.
The problem is, it never happens. When I debugged it, it seemed the program never assigns true to the premise current.content.Equals(searched), even when the two object is exactly identical.
What could be the problem?
If you never override the Equals() method in the Photo class to do the comparisons of the properties you've described, your code will be doing an object reference equality comparison.
This would explain why when the properties are identical, the Equals() method returns false.
Does anyone have any examples or ideas on how / what is the best way to implement a Stack class in C#? I understand that there is already a Stack class, but I need to understand how to actually implement a Stack class.
I also need advice on how to use Contracts in C# to specify preconditions, postconditions, and invariants for this class. I think I have used something similar before when creating models in the ASP.NET MVC architecture, but I'm not entirely sure if it is the same thing and works the same way. (I'm a bit lost on the preconditions/postconditions/invariants, if you couldn't already tell - so please bear with me.)
My main question - could someone give me advice on properly using Contracts for a class such as a Stack.
Yes, I have laid out effort:
public interface IStack
{
void Push(Object e);
Object Pop();
Object Top();
void EnsureCapacity();
}
}
public class Stack : IStack
{
private Object[] elements;
private int size = 0;
public Stack()
{
elements = new Object[0];
}
public void Push(Object e)
{
// check if this array capacity has been reached and increase if needed
EnsureCapacity();
elements[size++] = e;
}
public Object Pop()
{
// check if the method call is invalid for the object's current state
if (size == 0) throw new InvalidOperationException("Stack.Pop");
Object result = elements[--size];
elements[size] = null;
return result;
}
public Object Top()
{
// check if the method call is invalid for the object's current state
if (size == 0) throw new InvalidOperationException("Stack.top");
return elements[(size - 1)];
}
private void EnsureCapacity()
{
if (elements.Length == size)
{
Object[] oldElements = elements;
elements = new Object[(2 * size + 1)];
}
}
}
If you want, for getting started using Microsoft Code Contracts, I made a blog post about it once. That post covers the very basic of preconditions, post-conditions, and invariants.
As a summary of the concepts, you can think of them as follows:
Precondition is what must be true prior to a method being executed -- what clients promise your method.
Invariant is what must remain publicly true at all times as far as clients of your class are concerned.
Postcondition is what must be true following a method execution -- what your method promises to clients.
So, off the top of my head, for a stack, an easy thing to think of might be an invariant. If you're modeling the stack with an array, you might declare an invariant on the class that the array is never set to null, for example you'd define the invariant method:
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(elements != null);
}
It looks like you've already got a precondition on your pop method - you want to say that it's incumbent on the user to make sure that the stack is not empty when he executes a pop. So, at the beginning of the pop method, you'd have:
Contract.Requires(size > 0);
And finally, you might specifiy a post-condition on pop, that size will always be less than it was before the pop operation (you could get more specific if you like):
Contract.Ensures(Contract.OldValue<int>(size) > size);
Good luck with it -- contracts are cool and useful. It's a very clean way to code.
Many of collections implemented in c# are based on arrays. You could use array and add elements to the end, keep index of a top elemnet and increase it while new elements are pushed, of course array will "have to be extended" ( replaced by new one ) dynamically when new objects appear and there is no place for them in current array.
code contracts have pretty good documentation available at http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf
I need to find out how to perform some action (flush cache) when an object of type X is updated.
So when I save object of type Y, nothing is done, when I save unchanged object of type X nothing should happen, but when this object is changed and UPDATE is made, I want to know it.
I tried various NHibernate events (IPostUpdateEventListener, IFlushEntityEventListener, etc.) but did not succeed.
You want an IPostUpdateEventListener.
I was experiencing problem in implemented method, because in some cases I had to call the same method on default implementation, otherwise the code path ended in my code.
private readonly DefaultFlushEntityEventListener _impl = new DefaultFlushEntityEventListener();
public void OnFlushEntity(FlushEntityEvent flushEntityEvent)
{
... my code goeas here ...
_impl.OnFlushEntity(flushEntityEvent);
}
In OnFlush method of IFlushEntityEventListener I cannot detect dirty properties... etc.
But what really works is (thanks Andrew) is this code
public void OnPostUpdate(PostUpdateEvent postUpdateEvent)
{
var dirtyProperties = postUpdateEvent.Persister.FindDirty(postUpdateEvent.State, postUpdateEvent.OldState, postUpdateEvent.Entity, postUpdateEvent.Session);
int dirty = dirtyProperties.Length;
if (dirty == 0) // I want detect only modififed entities
return;
Trace.WriteLine(string.Format("OnPostUpdate({0}, {3}) in session#{1} - dirty props. {2}", postUpdateEvent.Entity.GetType().Name, postUpdateEvent.Session.GetHashCode(), dirty, postUpdateEvent.Entity.GetHashCode()));
lock (_objects)
{
if (!_objects.Contains(postUpdateEvent.Entity)) // I will manipulate this list in `AbstractFlushingEventListener.PostFlush` method
_objects.Add(postUpdateEvent.Entity);
}
}