I'm confused about how to use the MemberwiseClone() method. I looked the example in MSDN and they use it trough the this keyword.
Why I can not call it directly as other objects' methods like GetType() or ToString()? Another related method that does not appear is ShallowCopy().
If they are part of the Object class why can't I see them?
The MemberwiseClone() function is protected, so you can only access it through a qualifier of your own type.
Here is an example, this is what I did and no problems so far.
public class ModelBase
{
public T ShallowCopy<T>() where T : ModelBase
{
return (T)(MemberwiseClone());
}
}
And call it like:
var cloned = User.ShallowCopy<User>();
Related
With those classes:
public abstract class T_BaseClass
{
public virtual void m_canvas()
{
Console.WriteLine("canvas method called from template.");
}
}
public class C_ChildT : T_BaseClass
{
public override void m_canvas()
{
base.m_canvas();
Console.WriteLine("canvas method called from child template.");
}
}
What is the differences between those two implementations?
Difference between
C_ChildT mychildclass = new C_ChildT();
and
T_BaseClass mychildclass1 = new C_ChildT();
mychildclass.m_canvas();
mychildclass1.m_canvas();
Hope it looks better M.Skeet.
Thank you for your answer.
Basically, you don't need a deep understanding of inheritance to work with it. The minimum, that you should know is that the last child of inheritance sequence methods is called, when you call any method on an object. Also you should know that variable type and object type are different things, and you can store an object of child types in a variable of parent type. So, in your example you have two variables with C_ChildT and T_BaseClass types. But both objects are C_ChildT type. So when you call m_canvas() on each of them, you will call the C_ChildT implementation of m_canvas() in both cases.
Under the hood, when you call a virtual method, your runtime evironment sees, that the method is marked with the virtual keyword, so it (runtime environment) starts looking for overrriding of this method in the most derived class. You can read more about it here.
I have an asbtract class and I have classes that are devired from it. I have an attribute called PluginEventAttribute that works like so:
[PluginEventAttribute(PluginEvent.Load)]
public void OnLoad()
{
Log("Test Plugin loaded!");
}
I want my code to check if there is a method that uses that attribute, and if so, call it with custom parameters. How can I do that in C# winforms?
You just have to enumerate the instance methods and call the method if it has said attribute. Here's a working example (I hope I got your intent correctly) :
using System;
using System.Reflection;
class Program
{
class MyAttr : Attribute { }
abstract class Base { };
class Derived : Base
{
[MyAttr]
public void foo() { Console.WriteLine("foo"); }
public void bar() { Console.WriteLine("bar"); }
}
static void Main()
{
Base someInstance = new Derived();
foreach (var m in someInstance.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance))
{
if (m.GetCustomAttribute(typeof(MyAttr)) != null)
{
m.Invoke(someInstance, null); // prints "foo"
}
}
Console.ReadLine();
}
}
You may change the null argument in the call to Invoke to the array of arguments you wish to pass to the function. The contents of that array must match the function signature.
This has nothing to do with WinForms. It's all about CLR runtime and its type system.
I don't know any way how you could "just do it".
You can check if a method M has an attribute A only if you have a MethodInfo object that describes that method (methodinfo.GetCustomAttributes())
You can get MethodInfos in several ways, but the easiest and most obvious is to get the Type object and ask it about its methods (type.GetMethod()/type.GetMethods()).
You can get a Type object in several ways too. If you have any object at hand, you can call its GetType() method. Or, you can ask an Assembly object (that describes a DLL or EXE) about the Types it defines. (..)
So, if you have a foo object that someone already created:
call foo.GetType()
loop over type.GetMethods()
call method.GetCustomAttributes(typeof(YourAttribute))
check if it was found
Now if you notice that it as been found, you will end up having a MethodInfo that matches a method with that attribute. The only thing left is to call that method with methodinfo.Invoke and to pass it both parameters and the foo object.
Situation gets tricky if you don't have a foo object that you want to scan for methods. You must get the whole assembly, scan all types, scan all their methods. You end up with matching MethodInfo again. But you don't have any object to call the method found upon. Either that method will need to be static (so callable without target object) or you will need to somehow get matching object, too.
Coming from a C++ background, I'm used to sticking the const keyword into function definitions to make objects being passed in read-only values. However, I've found out that this is not possible in C# (please correct me if I'm wrong). After some Googling, I arrived at the conclusion that the only way to make a read-only object is to write an interface that only has 'get' properties and pass that in instead. Elegant, I must say.
public interface IFoo
{
IMyValInterface MyVal{ get; }
}
public class Foo : IFoo
{
private ConcreteMyVal _myVal;
public IMyValInterface MyVal
{
get { return _myVal; }
}
}
I would pass it into:
public void SomeFunction(IFoo fooVar)
{
// Cannot modify fooVar, Excellent!!
}
This is fine. However, in the rest of my code, I would like to modify my object normally. Adding a 'set' property to the interface would break my read-only restriction. I can add a 'set' property to Foo (and not IFoo), but the signature expects an interface rather than a concrete object. I would have to do some casting.
// Add this to class Foo. Might assign null if cast fails??
set { _myVal = value as ConcreteMyVal; }
// Somewhere else in the code...
IFoo myFoo = new Foo;
(myFoo as Foo).MyFoo = new ConcreteMyVal();
Is there a more elegant way of replicating const or making read-only function parameters without adding another property or a function?
I think you may be looking for a solution involving two interfaces in which one inherits from the other:
public interface IReadableFoo
{
IMyValInterface MyVal { get; }
}
public interface IWritableFoo : IReadableFoo
{
IMyValInterface MyVal { set; }
}
public class Foo : IWritableFoo
{
private ConcreteMyVal _myVal;
public IMyValInterface MyVal
{
get { return _myVal; }
set { _myVal = value as ConcreteMyVal; }
}
}
Then you can declare methods whose parameter type “tells” whether it plans on changing the variable or not:
public void SomeFunction(IReadableFoo fooVar)
{
// Cannot modify fooVar, excellent!
}
public void SomeOtherFunction(IWritableFoo fooVar)
{
// Can modify fooVar, take care!
}
This mimics compile-time checks similar to constness in C++. As Eric Lippert correctly pointed out, this is not the same as immutability. But as a C++ programmer I think you know that.
By the way, you can achieve slightly better compile-time checking if you declare the type of the property in the class as ConcreteMyVal and implement the interface properties separately:
public class Foo : IWritableFoo
{
private ConcreteMyVal _myVal;
public ConcreteMyVal MyVal
{
get { return _myVal; }
set { _myVal = value; }
}
public IMyValInterface IReadableFoo.MyVal { get { return MyVal; } }
public IMyValInterface IWritableFoo.MyVal
{
// (or use “(ConcreteMyVal)value” if you want it to throw
set { MyVal = value as ConcreteMyVal; }
}
}
This way, the setter can only throw when accessed through the interface, but not when accessed through the class.
The closest equivalent is the in keyword. Using in makes the parameter and input parameter and prevents it from being changed inside the method. From the official C# documentation:
in - specifies that this parameter is passed by reference but is only read by the called method.
ref - specifies that this parameter is passed by reference and may be read or written by the called method.
out - specifies that this parameter is passed by reference and must be written by the called method.
First of all, you're correct: you cannot apply const or a similar keyword to parameters in C#.
However, you can use interfaces to do something along those lines. Interfaces are special in the sense, that it makes perfect sense to make an interface that only covers a specific part of a feature set. E.g. image a stack class, which implements both IPopable and IPushable. If you access the instance via the IPopable interface, you can only remove entries from the stack. If you access the instance via the IPushable interface, you can only add entries to the stack. You can use interfaces this way to get something similar to what you're asking for.
Consider Timwi's answer first. But as a second option, you could do this, making it more like the C CONST keyword.
Reference-type (object) parameters are IN parameters by default. But because they are references, their method side effects and property accesses are done to the object outside the method. The object doesn't have to be passed out. It has still been modified by the method.
However, a value-type (struct) parameter is also IN by default, and cannot have side effects or property modifications on the element that was passed in. Instead, it gets COPIED ON WRITE before going into the method. Any changes to it inside that method die when the method goes out of scope (the end of the method).
Do NOT change your classes to structs just to accommodate this need. It's a bad idea. But if they should be structs anyway, now you'll know.
BTW, half the programming community doesn't properly understand this concept but thinks they do (indeed, I've found inaccuracies on the matter of parameter direction in C# in several books). If you want to comment on the accuracy of my statements, please double check to make sure you know what you're talking about.
I have a method:
public void StoreUsingKey<T>(T value) where T : class, new() {
var idModel = value as IIDModel;
if (idModel != null)
Store<T>(idModel);
AddToCacheUsingKey(value);
}
that I would like to optionally call the following method, based on the value parameter's implementation of IIDModel.
public void Store<T>(T value) where T : class, IIDModel, new() {
AddModelToCache(value);
}
Is there a way to tell Store<T> that the value parameter from StoreUsingKey<T> implements IIDModel? Or am I going about this the wrong way?
Rich
Answer
Removing the new() constraint from each method allows the code to work. The problem was down to me trying to pass off an interface as an object which can be instantiated.
You already are. By putting the IIDModel constraint on the Store<T> method, you're guaranteeing, that the value parameter implements IIDModel.
Oh, ok I see what you're saying now. How about this:
public void StoreUsingKey<T>(T value) where T : class, new() {
if (idModel is IIDModel)
Store<T>((IIDModel)idModel);
AddToCacheUsingKey(value);
}
Edit yet again: Tinister is right. This by itself won't do the trick. However, if your Store method looks like what Joel Coehoorn posted, then it should work.
public void Store(IIDModel value) {
AddModelToCache(value);
}
Removing the new() constraint from each method allows the code to work. The problem was down to me trying to pass off an interface as an object which can be instantiated.
I've defined the following generic class
public class ManagedClass<T> where T : ManagedClass<T>
{
static ManagedClass()
{
Manager = new ObjectManager<T>();
}
public static ObjectManager<T> Manager { get; protected set; }
public ManagedClass()
{
Manager.Add( (T)this );
}
}
The idea is that I can use it like so:
class Product : ManagedClass<Product> {}
Now I can do something to the 7th product created like so:
Product.Manager.GetById(7).DoSomething();
The problem comes in if i try to use a derived class:
class ExtendedProduct : Product {}
now ExtendedProduct.Manager has a list of 'Products', and if i want to use a new function that I have added to ExtendedProduct (DoSomethingElse), I have to cast the object I get back like so:
((ExtendedProduct)ExtendedProduct.Manager.GetById(7)).DoSomethingElse();
This is a bit ugly, and the whole point of using generics for this is to avoid casting. I suppose I could add a static constructor to the derived class to set Manager = new ObjectManager() and add a new Manager.addObject( this ) in the derived class constructor, but It seems like there should be some better way of doing this using generics. Any suggestions?
The problem is that ExtendedProduct.Manager is the same thing as Product.Manager; the manager object can't act differently depending on where it's accessed from.
A couple of possibilities I can think of:
Hide the typecast inside the GetById method by making it generic:
Product.Manager.GetById<ExtendedProduct>(7).DoSomethingElse();
Use one ObjectManager instance per subclass, connecting them privately if needed
Option 1 reminds me of NHibernate's ICriteria interface. It's effectively the same as a typecast, but a little harder to accidentally break.
Really what you're running into is a weakness with Generics. Once your class has resolved what type it's using for generics, you're somewhat restricted in what you can do.
Normally, I'd say Dependency Injection would be a savior here, but since the problematic method is static, that muddies up the waters.
I'd say the best thing is to have the ObjectManager class do the work for you:
static public class ObjectManager<T>
{
... the code that already exists in ObjectManager ...
static public U GetById<U>(long id)
{
object obj = GetById(id);
if (obj is U)
return (U)obj;
return default(U);
}
}
Then, in your code:
ExtendedProduct.Manager.GetById<ExtendedProduct>(7).DoSomethingElse();
It's not really tons more elegant than casting, but may be one of the only solutions using Generics.