today I saw a snipped that looked really horrible to me, but unfortunetly I cannot simply change it, so I wonder if I can bypass this somehow. I have a class with a constructor that has an output-parameter for success. But that looks really ugly to me. And now when deriving from this class I have to take this param with me- if I want to or not.
class ClassA {
ClassA(out bool success) {...}
}
class B: ClassA {
// call the constructor from ClassA but without the out-param
}
So I´d know if its good practise or if not how I can avoid declaring the out-param from ClassB.
While passing ref or out parameters to a constructor is ugly, there are some types where attempts to create a usable instance will have side-effects, and might fail after some of those side-effects have already occurred. If it is not possible to construct a valid object, the only ways via which the constructor can pass information to the caller are by storing it in a threadstatic field, encapsulating it within the thrown exception, storing or feeding it to a passed-in object or delegate, or writing it to a ref/out parameter. Of those, only the ref/out parameter makes obvious the existence of information with which the client code should be doing something.
The existence of ref or out parameters is often an indication that a constructor should be protected, and that outside code should go through a factory methods which ensure that if an exception is thrown the passed-out object will get used suitably. For a class to reasonably support inheritance, however, it must offer at least one constructor which is visible outside it. Having that constructor use an out or ref parameter may be the least evil way for a class to let a caller know what things will need cleaning up if construction fails.
You can do something like this:
class ClassA
{
protected ClassA(out bool success)
{
success = true;
}
}
class B : ClassA
{
[ThreadStatic]
static bool success; // static to use in base(out success) call
public bool Success
{
get;
private set;
}
public B()
: base(out success)
{
Success = success;
success = false; // reset value
}
}
It's ugly, but at least you get rid of the out parameter if so you want.
Well, the design of that class is broken anyway, so let's break it a bit more (NOTE! I do not recommend this approach!):
void Main()
{
}
public class ClassA
{
public ClassA(out bool success)
{
success = true;
}
}
public class B: ClassA
{
private static bool success;
// call the constructor from ClassA but without the out-param
public B()
: base(out success)
{
}
}
Other than that, the closest you can get is making a factory method:
public class B : ClassA
{
public static B Create()
{
bool success;
var result = new B(out success);
if (success)
return result;
// TODO: Dispose result?
throw new StupidProgrammerException();
}
}
If you really don't care about the value of the out parameter, in newer versions of C# you can declare an out variable inline and you can choose to do nothing with it:
class B : ClassA
{
B() : base(out bool ignore) { }
}
You can go further and use the special discard name _ to let the compiler know you won't use the variable. This way you don't even need to declare its type:
class B : ClassA
{
B() : base(out _) { }
}
Related
Can I call a constructor from same class method in C#?
Example:
class A
{
public A()
{
/* Do Something here */
}
public void methodA()
{
/* Need to call Constructor here */
}
}
The short answer is No :)
You cannot call constructors as simple methods except these special cases:
You create a new object: var x = new ObjType()
You call a constructor from another constructor of the same type:
class ObjType
{
private string _message;
// look at _this_ being called before the constructor body definition
public ObjType() :this("hello")
{}
private ObjType(string message)
{
_message = message;
}
}
You call a base type constructor from a constructor:
class BaseType
{
private string _message;
// NB: should not be private
protected BaseType(string message)
{
_message = message;
}
}
class ObjType : BaseType
{
// look at _base_ being called before the constructor body execution
public ObjType() :base("hello")
{}
}
UPD. Regarding the workaround with an initialization method proposed in another answer - yes, it's probably a good way. But it's a bit tricky because of the object consistency, which is the reason why constructors are even exist. Any object method is expected to receive the object (this) in a consistent (working) state. And you cannot guarantee it calling a method from a constructor. So any person editing that initialization method or calling constructor in future (probably you) could expect having this guarantee which greatly increases the risk of making mistake. The problem is amplified when you deal with inheritance.
Besides provided answer which answers the question, an easy away to fix your problem is to define an initialization method that is called from both the constructor and your method:
class A
{
private init()
{
// do initializations here
}
public A()
{
init();
}
public void methodA()
{
// reinitialize the object
init();
// other stuff may come here
}
}
Shortly put, you cannot call the constructor, but you don't have to :)
In my project, I have many DLL assemblies referenced. One of those DLL's contains the bool method that I want to change. I do not have the original source for the DLL and using a Reflector to decompile a project seems impractical. All I want to do is intercept or override this method or method call so that I can change it's return value to match my own method outside of said DLL.
Any such way to do this? Thanks!
Edit:
Here is an example:
public virtual bool isOwner()
{
return false;
}
Essentially, I just want to change getOwner to return true;
If the class is public and the method is marked as virtual, then you can simply override it with this syntax:
public MyClass : TheClass
{
public override ReturnType MethodName(Arguments)
{
//class the base class implementation if needed
//base.MethodName(Arguments)
//do your own stuff and return whatever is needed
}
}
Hope this helps
EDIT: A word of caution though, this won't replace the calling code within the DLL. It will only work if you instantiate the derived class yourself and call it from your code.
Is there a general way to do what you want, built into .NET?
Yes, and no.
If you want every usage of class X' method Y to be replaced by some other code, then no, there is nothing built into .NET class system or compiler that will do this.
If you can inherit from class X, overriding method Y, and then ensure that all places where class X is used, your new class is used instead, then yes, that is the proper way to do this.
This is easily done:
public class YourFixedClass : TheProblematicClass
{
public override string YourProblematicMethod()
{
// probably call the problematic method through base.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
Or, if you can make a new class that implements all the same interfaces, wrapping (delegating) all the methods and properties of the original (problematic) class, then that might be doable, but this requires all actual usage of the class to go through the interfaces.
As this:
public class Wrapper : IInterface1, IInterface2
{
private readonly YourProblematicClass _C;
public Wrapper(YourProblematicClass c)
{
_C = c;
}
public string YourProblematicMetho()
{
// probably call the problematic method through _C.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
If, on the other hand, you don't have control of where all the code is that calls the class/method, then no, you can't do any of this.
So what else is there? Well, there is always the debugger interfaces. You can make a program that is somehow the debugger of itself, patching in the right code upon demand, but this is likely to be extraordinary difficult to get right.
In short, no, there is no way to do what you want. You need to find a different way to accomplish this.
Have you thought about changing the original assembly in the first place? I understand that you don't have the source code for it, but is that because:
You lost it
You didn't make it
In point 1, I would really work towards recreating the source code, either through a decompiler or similar, and get a new project going to fix that.
In point 2, have you thought about contacting the people that made it and asking them for help?
Uhm Ok you can do something like this:
public class MyNameClass : MyDllname.MyClassName
{
public bool isOwner()
{
return !base.isOwner();
}
}
Then you have override the method and you can use all the other methods in the DLL simply using an istance(if there aren't static) of the MyNameClass
You can use "new" modifier.
See example on http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
Or this:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new ClassA().IsEvenDayToday()); // Result: true
Console.WriteLine(new ClassB().IsEvenDayToday()); // Result: false
Console.ReadKey();
}
}
public class ClassA : ClassB
{
public new bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 == 0;
}
}
public class ClassB
{
public bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 != 0;
}
}
I have the following function in c#:
bool Handle<TCommandHandler, TModel>(TModel model) where TCommandHandler : ICommandHandler<TModel> {
// ...
_container.Resolve<TCommandHandler>();
// ...
}
Since TModel is clear from a function parameter I want some way to not specify its type when calling a function. Ideally I want to call it like:
Handle<MyCommandHandler>(model);
Since this is probably impossible, I came up with the following:
HandleTemp<TModel> Handle<TModel>(TModel model) {
return new HandleTemp<TModel>(model);
}
public class HandleTemp<TModel> {
private TModel _model;
public HandleTemp(TModel model) { _model = model;}
public bool With<TCommandHandler>() where TCommandHandler : ICommandHandler<TModel> {
}
}
So I'm now calling it like:
Handle(model).With<MyCommandHandler>();
Are there other possibilities? Did I make something completely wrong with my solution?
No, your analysis and solution look about right. Indeed, generic type inference can work only on an all-or-nothing basis. If there are some generic parameters that can't be inferred, all must be explicitly stated. Personally I'd quite like a way to say "you worry about these parameters, I'll tell you this one", but... that doesn't exist.
The only other option is to add an artificial extra regular parameter to allow it to infer the generic parameter - a bit yucky.
One other option: challenge the assumption that generics are needed here. For example, could it just be a Type instance? Would:
bool Handle<TModel>(TModel model, Type type)...
...
Handle(model, typeof(MyCommandHandler));
work, for example? I can't answer this directly, as I don't know the particulars of your _container.Resolve<TCommandHandler>(); method, as to whether that could be adjusted to take a Type rather than a <T>.
All the C# compiler needs is a demonstration of the type in the arguments, so instead of attempting to place it in the generic arguments (at the usage site) make something that lets you provide an argument that helps the compiler identify that type. To make it less confusing, here is an example:
// Your classes/interfaces.
class Container
{
public static T Resolve<T>()
{
Console.WriteLine("Resolving {0}", typeof(T).FullName);
return default(T);
}
}
interface ICommandHandler<TModel>
{
void DoSomething();
}
// An implemented ICommandHandler.
public class WackyCommandHandler : ICommandHandler<string>
{
public void DoSomething() { }
}
// Used to help the C# compiler identify types.
public static class Identify
{
public static TypeIdentity<TType> TheType<TType>()
{
return null; // You don't actually need an instance.
}
}
public sealed class TypeIdentity<TType>
{
private TypeIdentity() { }
}
// Your method
static bool Handle<TCommandHandler, TModel>(TModel model, TypeIdentity<TCommandHandler> handler)
where TCommandHandler : ICommandHandler<TModel>
{
var item = Container.Resolve<TCommandHandler>();
return true;
}
// And the usage site:
var a = "hello";
Handle(a, Identify.TheType<WackyCommandHandler>());
Console.ReadLine();
Is there a way to do so as it seems partial method must return void (I really don't understand this limitation but let it be) ?
Well, technically you can "return" a value from a partial method, but it has to be through a ref argument, so it's quite awkward:
partial void Foo(ref int result);
partial void Foo(ref int result)
{
result = 42;
}
public void Test()
{
int i = 0;
Foo(ref i);
// 'i' is 42.
}
In that example, the value of i won't change if Foo() is not implemented.
From MSDN:
Partial method declarations must begin with the contextual keyword partial and the method must return void.
Partial methods can have ref but not out parameters.
So the answer is no, you can't.
Perhaps if you explain a bit more about your situation (why you need to return a value, why the class is partial), we can provide a workaround.
You cannot return a value from a partial method.
Partial methods may or may not be implemented. If it were permitted to return a value from such a method, then what would the caller receive?
The reason for the restriction is this line from MSDN:
A partial class or struct may contain
a partial method. One part of the
class contains the signature of the
method. An optional implementation may
be defined in the same part or another
part. If the implementation is not
supplied, then the method and all
calls to the method are removed at
compile time. -- Emphasis Mine
If the method may not be implemented and can be removed. What would happen to its return value if the call is removed?
As to your question of a work around, that depends on what you are trying to do, but obviously you can't use a partial method.
Oh. Once I had to do this in a project of mine.
You can throw an exception in your method called ReturnValueException which you define as an exception that has an object property named ReturnedValue. Now you can call your method Foo() inside a try block and collect the results in the catch block.
No.. just kidding.
Don't do that. Ever.
Here's a technique relying on the fact that an extension method will be shadowed by a class method.
It's more involved and less clear than the ref parameter technique, so I'll use that instead.
Several shadowing mechanisms in C# could be used instead: using static vs. method, a parent class containing just the default behaviour vs. a new method, a method accepting a dummy object vs. a method with a more specific argument type etc.
The choice between the extension method or the class method when it is present is made at compile-time (that is, it doesn't use late binding). This can lead to some problems if your partial class is not sealed: if you override the customizable method with an implementation which is also customizable, you need to use a fresh interface and extension method
https://repl.it/#suzannesoy/WorthwhileSplendidBotany#main.cs
// On the auto-generated side:
interface IDefaultFoo { int DefaultFoo(); }
static class DefaultFoo {
public static int CustomFoo(this IDefaultFoo o) => o.DefaultFoo();
}
partial class PartialClass : IDefaultFoo {
int IDefaultFoo.DefaultFoo() => 42;
// mark as virtual if you want to override in subclasses too.
public virtual int Foo() => this.CustomFoo();
}
// On the user side:
partial class PartialClass {
// Define this method only if you want to change
// the default implementation of Foo.
public int CustomFoo() => 123;
}
// In subclasses use override on the Foo method as usual
class SubClass1 : PartialClass {
public new int CustomFoo() => 666; // This is not used
public override int Foo() => 999; // Use this instead
}
// If you also want to override in the subclass with a method which
// is also customizable, i.e. to provide a new default behaviour in
// the partial subclass that could also be customized, you'll need
// to add a new interface etc. otherwise the CustomFoo from the
// parent class would be called because it still shadows the
// extension method.
interface IDefaultFooSub2 { int DefaultFoo(); }
static class DefaultFooSub2 {
public static int CustomFooSub2(this IDefaultFooSub2 o) => o.DefaultFoo();
}
partial class SubClass2 : PartialClass, IDefaultFooSub2 {
int IDefaultFooSub2.DefaultFoo() => 1000000;
public override int Foo() => this.CustomFooSub2();
}
class MainClass {
public static void Main (string[] args) {
System.Console.WriteLine(new PartialClass().Foo()); // 123
System.Console.WriteLine(new SubClass1().Foo()); // 999
System.Console.WriteLine(new SubClass2().Foo()); // 1000000
System.Console.WriteLine(((PartialClass)new SubClass2()).Foo()); // 1000000
}
}
In the code below I tried in two ways to access the parent version of methodTwo, but the result was always 2. Is there any way to get the 1 result from a ChildClass instance without modifying these two classes?
class ParentClass
{
public int methodOne()
{
return methodTwo();
}
virtual public int methodTwo()
{
return 1;
}
}
class ChildClass : ParentClass
{
override public int methodTwo()
{
return 2;
}
}
class Program
{
static void Main(string[] args)
{
var a = new ChildClass();
Console.WriteLine("a.methodOne(): " + a.methodOne());
Console.WriteLine("a.methodTwo(): " + a.methodTwo());
Console.WriteLine("((ParentClass)a).methodTwo(): "
+ ((ParentClass)a).methodTwo());
Console.ReadLine();
}
}
Update ChrisW posted this:
From outside the class, I don't know
any easy way; but, perhaps, I don't
know what happens if you try
reflection: use the Type.GetMethod
method to find the MethodInfo
associated with the method in the
ParentClass, and then call
MethodInfo.Invoke
That answer was deleted. I'm wondering if that hack could work, just for curiosity.
Inside of ChildClass.methodTwo(), you can call base.methodTwo().
Outside of the class, calling ((ParentClass)a).methodTwo() will call ChildClass.methodTwo. That's the whole reason why virtual methods exist.
At the IL level, you could probably issue a call rather than a callvirt, and get the job done - but if we limit ourselves to C# ;-p (edit darn! the runtime stops you: VerificationException: "Operation could destabilize the runtime."; remove the virtual and it works fine; too clever by half...)
Inside the ChildClass type, you can use base.methodTwo() - however, this is not possible externally. Nor can you go down more than one level - there is no base.base.Foo() support.
However, if you disable polymorphism using method-hiding, you can get the answer you want, but for bad reasons:
class ChildClass : ParentClass
{
new public int methodTwo() // bad, do not do
{
return 2;
}
}
Now you can get a different answer from the same object depending on whether the variable is defined as a ChildClass or a ParentClass.
As mentioned above, something is bad with your class design if you need to call "base.base" in PRODUCTION code. But it is quite legitimate to use this technique if you are debugging or searching some workarrounds while using external libraries you cannot compile. It is unpleasant that C# does not provide this option directly. Still you may use Kenneth Xu solution with IL generator and Emit. It works.
class A { public virtual string foo() { return "A"; } }
class B : A { public override string foo() { return "B"; } }
// now in class C
class C : B {}
// we can call virtual method "foo" from A using following code
MethodInfo fooA = typeof(A).GetMethod("foo", BindingFlags.Public | BindingFlags.Instance);
DynamicMethod baseBaseFoo = new DynamicMethod(
"foo_A",
typeof(string),
new[] { typeof(A) },
typeof(A));
ILGenerator il = baseBaseFoo.GetILGenerator();
il.Emit(OpCodes.Ldarg, 0);
il.EmitCall(OpCodes.Call, fooA, null);
il.Emit(OpCodes.Ret);
// call foo() from class A, it returns "A"
(string)baseBaseFoo.Invoke(null, new object[] { this });
For reference and a complete sample see
http://kennethxu.blogspot.cz/2009/05/cnet-calling-grandparent-virtual-method.html
Thank you Kenneth Xu!
As Mark Gravell said, no, not externally. But here's another hack I have used. ChildClass can expose methodTwo() from the ParentClass for its own use or for external use. In your case:
class ChildClass : ParentClass {
override public int methodTwo() {
return 2;
}
public int ParentClass_methodTwo() {
return base.methodTwo();
}
}
// Now instead of
Console.WriteLine("ParentClass methodTwo: " + ((ParentClass)a).methodTwo());
// use
Console.WriteLine("ParentClass methodTwo: " + a.ParentClass_methodTwo());
In my case, the child class introduced the concept of a Peer, and I needed its override of methodTwo() to invoke the base version on the peer. By overridding it, however, it hid it... Or did it? This technique came to the rescue.
class ChildClass : ParentClass {
ChildClass peer;
override public int methodTwo() {
return peer.ParentClass_methodTwo();
}
private int ParentClass_methodTwo() {
return base.methodTwo();
}
}
To my knowledge, once a method has been overridden then you can't call the parent method.
public class Parent
{
public string Method()
{
return "parent";
}
}
public class Child:Parent
{
public string Method()
{
return "child";
}
}
Above code successfully overrides parent method yet value of parent method still unchanged.
You can return values from the Both Parent class and Child class using code below -
Child child = new Child();
string result = (((Parent)child).Method()) + child.Method();
But Visual Studio will show you a warning in Compile Time.
I would think that it is not possible unless you make instance of the ParentClass directly.
Thats the very essense of inheritance, polymorphism...
I stumbled upon this looking for help and ended up with my own approach to calling ancestor versions of a method. This is more of a work-around which assumes you can edit the ancestor class:
Put the functionality in question in the ancestor class into a static method, with the necessary parameters. The method in that class can call it so it need not duplicate the functionality, and the child class can call to that functionality if desired via the static method. That way, it can be done even within a method and can cite which specific class it wants to invoke. Also, it can access farther back ancestors than mere parents, which is the limitation of use "base".