I have groups of logic that consist of static classes such as:
static class A {
static int mutate(int i) { /**implementation*/ };
static double prop(double a, double b) { /**implementation*/ };
}
static class B {
static int mutate(int i) { /**implementation*/ };
static double prop(double a, double b) { /**implementation*/ };
}
In this case, A and B are static classes that implement the same behavior via a group of functions (e.g. mutate). I would like to use something like an interface for this pattern, however since static classes cannot implement interfaces I am not sure what to do. What is the best way to implement this type of behavior cleanly?
EDIT:
Here is an example of what I am currently doing. The classes have no state so normally I would make them static.
Interface IMutator {
int mutate(int i);
}
class A : IMutator {
int mutate(int i) { /**implementation*/ };
}
class B : IMutator {
int mutate(int i) { /**implementation*/ };
}
class C {
public List<IMutator> Mutators;
public C(List<IMutator> mutators) {
Mutators = mutators;
}
}
//Somewhere else...
//The new keyword for A and B is what really bothers me in this case.
var Cinstance = new C(new List<IMutator>() {new A(), new B() /**...*/});
The stateless class doesn't have to be static.
Moreover, static dependencies isn't a good choice, when you want to write unit tests, or when you want to extract some common interface (as in your case).
It's OK to have non-static classes, containing logic only. E.g., people build ASP .NET applications using stateless controllers.
So, just throw away static and extract an interface.
Apart from #Dennis answer (which I have +1'ed, and it's indeed the way to go), other approach that may work, is having a set of functions (Func<>) and/or actions (Action<>) and resolve them using reflection. The code would not be specially elegant nor performant, but it works.
I've made a quick example on dotnetfiddle
Related
I have been spending a lot of time trying to find a library that allows to log information about the methods that are being executed. Somehow I feel that all of them are too invasive. Is there any library or code that makes this so simple that I only need to add a decorator/attribute to the method?
Here what I would like to have:
internal class Calculator
{
[CustomInterceptor]
public static int Add(int a, int b)
{
return a + b;
}
}
internal class CustomInterceptor : Attribute
{
//here some implementation
}
static void Main(string[] args)
{
var result = Calculator.Add(10, 2);
Console.WriteLine($"Result : {result}");
}
Desired output
Before Add
Result 12
After Add
If this can be done with Reflection, please I would prefer that approach since that would imply no need for third party libraries.
Thanks in advance.
Given
class Either<A, B> {
public Either(A x) {}
public Either(B x) {}
}
How to disambiguate between the two constructors when the two type parameters are the same?
For example, this line:
var e = new Either<string, string>("");
Fails with:
The call is ambiguous between the following methods or properties: 'Program.Either.Either(A)' and 'Program.Either.Either(B)'
I know if I had given the parameters different names (e.g. A a and B b instead of just x), I could use named parameters to disambiguate (e.g. new Either<string, string>(a: "")). But I'm interested in knowing how to solve this without changing the definition of Either.
Edit:
You can write a couple of smart constructors, but I'm interested in knowing if the Either's constructors can be called directly without ambiguity. (Or if there are other "tricks" besides this one).
static Either<A, B> Left<A, B>(A x) {
return new Either<A, B>(x);
}
static Either<A, B> Right<A, B>(B x) {
return new Either<A, B>(x);
}
var e1 = Left<string, string>("");
var e2 = Right<string, string>("");
How to disambiguate between the two constructors when the two type parameters are the same?
I'll start by not answering your question, and then finish it up with an actual answer that lets you work around this problem.
You don't have to because you should never get yourself into this position in the first place. It is a design error to create a generic type which can cause member signatures to be unified in this manner. Never write a class like that.
If you go back and read the original C# 2.0 specification you'll see that the original design was to have the compiler detect generic types in which it was in any way possible for this sort of problem to arise, and to make the class declaration illegal. This made it into the published specification, though that was an error; the design team realized that this rule was too strict because of scenarios like:
class C<T>
{
public C(T t) { ... }
public C(Stream s) { ... deserialize from the stream ... }
}
It would be bizarre to say that this class is illegal because you might say C<Stream> and then be unable to disambiguate the constructors. Instead, a rule was added to overload resolution which says that if there's a choice between (Stream) and (T where Stream is substituted for T) then the former wins.
Thus the rule that this kind of unification is illegal was scrapped and it is now allowed. However it is a very, very bad idea to make types that unify in this manner. The CLR handles it poorly in some cases, and it is confusing to the compiler and the developers alike. For example, would you care to guess at the output of this program?
using System;
public interface I1<U> {
void M(U i);
void M(int i);
}
public interface I2<U> {
void M(int i);
void M(U i);
}
public class C3: I1<int>, I2<int> {
void I1<int>.M(int i) {
Console.WriteLine("c3 explicit I1 " + i);
}
void I2<int>.M(int i) {
Console.WriteLine("c3 explicit I2 " + i);
}
public void M(int i) {
Console.WriteLine("c3 class " + i);
}
}
public class Test {
public static void Main() {
C3 c3 = new C3();
I1<int> i1_c3 = c3;
I2<int> i2_c3 = c3;
i1_c3.M(101);
i2_c3.M(102);
}
}
If you compile this with warnings turned on you will see the warning I added explaining why this is a really, really bad idea.
No, really: How to disambiguate between the two constructors when the two type parameters are the same?
Like this:
static Either<A, B> First<A, B>(A a) => new Either<A, B>(a);
static Either<A, B> Second<A, B>(B b) => new Either<A, B>(b);
...
var ess1 = First<string, string>("hello");
var ess2 = Second<string, string>("goodbye");
which is how the class should have been designed in the first place. The author of the Either class should have written
class Either<A, B>
{
private Either(A a) { ... }
private Either(B b) { ... }
public static Either<A, B> First(A a) => new Either<A, B>(a);
public static Either<A, B> Second(B b) => new Either<A, B>(b);
...
}
...
var ess = Either<string, string>.First("hello");
The only way I could think of would be to use reflection to iterate each constructor and then determine which one should be used based on the method body.
Of course this is way over the top and you should really just refactor your class, but it is a working solution.
It requires that you identify the byte[] for the method body that you want to use and 'hard code' that into the program (or read from file etc.). Of course you need to be very cautious that the method body may change over time, for example if the class is modified at any point.
// You need to set (or get from somewhere) this byte[] to match the constructor method body you want to use.
byte[] expectedMethodBody = new byte[] { 0 };
Either<string, string> result = null; // Will hold the result if we get a match, otherwise null.
Type t = typeof(Either<string, string>); // Get the type information.
// Loop each constructor and compare the method body.
// If we find a match, then we invoke the constructor and break the loop.
foreach (var c in t.GetConstructors())
{
var body = c.GetMethodBody();
if (body.GetILAsByteArray().SequenceEqual(expectedMethodBody))
{
result = (Either<string, string>)c.Invoke(new object[] { "123" });
break;
}
}
Disclaimer: Although I have tested this code briefly and it seems to work, I am really sceptical about how reliable it is. I do not know enough about the compiler to be comfortable in saying the method body wont change on a re-compile even if the code isn't changed. It may be that it would become more reliable if this class was defined in a pre-compiled DLL, again I don't know for sure though.
There may be other information you could get via reflection that might make it easier to identify the correct constructor. However, this was the first that came to mind and I haven't really looked into any other possible options at this time.
It would be much simpler if we could rely on the order of the constructors, but as quoted from MSDN, it is not reliable:
The GetConstructors method does not return constructors in a particular order, such as declaration order. Your code must not depend on the order in which constructors are returned, because that order varies.
I'm learning about C# extension methods at the moment. I have read in a couple of places that adding members to classes reduces backwards compatibility for code that uses those classes.
I've read this here:
https://blogs.msdn.microsoft.com/vbteam/2007/03/10/extension-methods-best-practices-extension-methods-part-6/
And page 418 of Troelson's Pro C# book.
I'm afraid this doesn't make sense to me. Surely any code that uses instances of those classes as they WERE before extra members were added (without using extension methods, just by adding them to the class), will still be able to call all the old methods, properties, fields and constructors just like before, as they haven't changed. Even if the new members can change the state of the object, they will never be called in the old code, so therefore the code is backwards compatible.
What am I not seeing here?
Here's one possible way adding a new method could actually break client code...
void Main()
{
var oldFoo = new OldFoo();
var oldResult = oldFoo.Calculate(2, 2); // 4
var newFoo = new NewFoo();
var newResult = newFoo.Calculate(2, 2); // 0
}
public class OldFoo
{
public int Calculate(params int[] values)
{
return values.Sum();
}
}
public class NewFoo
{
public int Calculate(params int[] values)
{
return values.Sum();
}
public int Calculate(int value1, int value2)
{
return value1 - value2;
}
}
And here's another way, specifically dealing with an extension method...
Initially, the client defines an extension method to give Foo the ability to Combine:
void Main()
{
var foo = new Foo();
var result = foo.Combine(2, 2); // "22"
}
public static class Extensions // added by client
{
public static string Combine(this Foo foo, params int[] values)
{
return string.Join(string.Empty, values.Select(x => x.ToString()));
}
}
public class Foo { }
Later, the developer of Foo adds a new Combine method to the class:
void Main()
{
var foo = new Foo();
var result = foo.Combine(2, 2); // 4
}
public static class Extensions
{
public static string Combine(this Foo foo, params int[] values)
{
return string.Join(string.Empty, values.Select(x => x.ToString()));
}
}
public class Foo
{
public int Combine(params int[] values)
{
return values.Sum();
}
}
Note that the extension method gets effectively blocked or shadowed by the new Combine instance method.
The point is that extension methods may share the same namespace with member methods and if they do, member methods take precedence sheerly by name. The implication of this is that you, as a library developer, may break code of a client who introduced an extension method to your class in his own application. Without you being able to know that you are doing it.
If you update your library class with a new member method and your client installs the update, he may find your new method has the same name as the extension method he added earlier. Or he may not find it if the argument lists are compatible. His extension method will now be hidden by your new member method. His code will now either not compile (incompatible argument list), or, worse, behave differently.
A real world analogy might help. Think about it like machinery. Imagine someone designs an engine that people start using as a basis for some equipment, say a harvester. If the engine designer decides a fuel filter would be helpful and adds that in, it could ruin the harvester design because that design may have put something in the space now occupied by the new fuel filter.
Adding the new member (the fuel pump) decreased the backwards compatibility. The harvester design was based on a version backward in history.
And a more programming based example: A app designer creates a parser for his application that behaves in a particular way. After release, it's discovered that the parser does not implement the spec correctly for some uncommon conditions. A new version is released that correctly implements the spec but adds a flag to provide the previous behavior.
The following test passes, but I'm wondering if a unified treatment is possible. Can it be done?
public abstract class MyInvokable<TResult> {
public abstract TResult Invoke();
}
public class IntInvokable: MyInvokable<int> {
public override int Invoke() {
return 12;
}
}
[Test()]
public void FunctionInvokeTest () {
Func<int> foo = () => 6;
IntInvokable bar = new IntInvokable();
int six = foo.Invoke();
int twelve = bar.Invoke();
Assert.AreEqual(6, six);
Assert.AreEqual(12, twelve);
/* Now, what I really want to do but can't, as far as I can tell:
List<SomeType> list = new List<SomeType>(){foo, bar};
Assert.AreEqual(6, list[0].Invoke());
Assert.AreEqual(12, list[1].Invoke()); */
}
EDIT: started a feature request with Microsoft here:
http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/10185579-create-an-iinvokable-t-interface
C# does not allow anything even remotely close to this type of dynamic behaviour.
But, it you do need to go this route, you can always use dynamic, basically signaling the compiler that all bets are off. This would work:
List<dynamic> list = new List<dynamic>(){foo, bar};
Assert.AreEqual(6, list[0].Invoke());
Assert.AreEqual(12, list[1].Invoke());
but you cannot guarantee in any way that whatever is in the list variable, actually has an Invoke method.
The feature most like this one is TypeScript's structural interfaces - as long as a type has all the methods / properties required by the interface, it's considered to implement the interface.
In C#, the only way that two different things can be considered as having a similar type, is for them to explicitly declare that they implement the same interface, or inherit the same base class.
It would be nice to be able to somehow have a structural semantics in C#, but it's not even on the roadmap, AFAIK.
To have a List<T> where the only requirement you want is that T has a parameterless Invoke method you need to bake that requirement into either an interface or a base class.
So either of these two would work:
public interface IInvokable
{
int Invoke();
}
var l = new List<IInvokable>();
or this:
public class Invokable
{
public virtual int Invoke() { ... }
}
var l = new List<Invokable>();
Obviously, now you need to wrap the delegate in that class, for instance like this:
public class FuncInvokable : IInvokable
{
private readonly Func<int> _Func;
public FuncInvokable(Func<int> func) { _Func = func; }
public int Invoke() { return _Func(); }
}
or... you could just place delegates into the list and wrap all objects in delegates instead:
var l = new List<Func<int>>();
l.Add(foo);
l.Add(() => bar.Invoke());
but there is no way to define this:
var l = new List<Type that has an Invoke method>();
This question came to my mind while I
am reading the post Why doesn't C#
support multiple inheritance?
from MSDN Blog.
At first look at the following code:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class A
{
int num;
public A()
{
num = 0;
}
public A(int x)
{
num = x;
}
public override int GetHashCode()
{
return num + base.GetHashCode();
}
}
class B : A
{
int num;
public B()
{
num = 0;
}
public B(int x)
{
num = x;
}
public override int GetHashCode()
{
return num + base.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
Console.Write(a.GetHashCode() + " " + b.GetHashCode());
Console.Read();
}
}
}
Object class is the ultimate base class of all classes. So it is the base class of A and B both in my program and also make A as a base class of B. So B has now two base class, one is A and another is Object. I override one method GetHashCode() of Object Class in class A and B both. But in class B, base.GetHashCode() method returns the return value of GetHashCode() method of class A. But I want this value from Object class. How can I get that?
B has only one base class, and that is A. A has one base class, and that is object. There is no multiple inheritance; object is only inherited by classes that don’t already inherit from something else.
If you still think you need to call object.GetHashCode(), there is a very hacky workaround to do this in the question How to invoke (non virtually) the original implementation of a virtual method?.
You could write a protected instance method in class A that exposes GetHashCode() from Object. Then call that protected method in class B.
No Class B merely has one base class, class A.
To understand, class A really should be written as:
class A : Object
But since that is required, it can be left off.
This may help you: http://itpian.com/Coding/5191-cant-v-have-Multiple-Inheritances-in-C-sharp---------.aspx
Yes, this doesn't relate to multiple inheritance at all (incidentally, I miss private inheritance more than multiple inheritance). This question is also quite a horrible thing to think about.
If you have control of class A, then fine:
class A
{
/*elide the stuff you already have*/
protected int GetBaseHashCode()
{
return base.GetHashCode();
}
}
class A : B
{
/*elide stuff already in example*/
public override int GetHashCode()
{
return num + GetBaseHashCode();
}
}
If you do not:
public class B : A
{
private static readonly DynamicMethod GRANDPARENT_GET_HASH_CODE;
static B()
{
MethodInfo gpGHC = typeof(object).GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Instance);
GRANDPARENT_GET_HASH_CODE = new DynamicMethod("grandParentGHC", typeof(int), new Type[] { typeof(object) }, typeof(object));
ILGenerator il = GRANDPARENT_GET_HASH_CODE.GetILGenerator();
il.Emit(OpCodes.Ldarg, 0);
il.EmitCall(OpCodes.Call, gpGHC, null);
il.Emit(OpCodes.Ret);
}
private int num;
public B()
{
num = 0;
}
public B(int x)
{
num = x;
}
public override int GetHashCode()
{
return num + (int)GRANDPARENT_GET_HASH_CODE.Invoke(null, new object[]{this});
}
}
Frankly, I would put that code in the category of "let us never speak of it again". I assume this is relating to some more general principle, since the hashcodes here are useless anyway, but I'm not sure what that more general principle is. Certainly it can sometimes be annoying when something is hidden from deriving classes we want to get at, but it can be much worse when the opposite happens.
Back in the days of VB6, coders in that language would often have to do rather nasty stuff involving getting the memory address of the v-table used for virtual call lookup, altering the memory protection, and then tweaking the bytes stored there by hand, because in "protecting" users from implementation details they kept some vital things away from them (you could not create enumerators without this technique, only pass on those for other objects).
Thank goodness we are not "protected" to that extent in C#. If I ever have to write code like the answer I gave above for a real project, I'm going to need a few drinks to recover later that evening.
Getting a hash of the base Object class is irrelevant to the purpose of the method. The whole point of GetHashCode() is to generate a unique (as possible) identity value based on the specific type and state of the object.
The GetHashCode() method uses a default hashing algorithm that can be used to determine instance identity and uniqueness, though uniqueness is not guaranteed. The default algorithm uses the state of the object to generate the hash.
More information: http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx
I'm afraid you are mixing normal inheritance with multiple inheritance. Multiple inheritance meand that you have 3 classes A is subclass of B and C but neither B is subclass of C nor C is subclass of B.
Normal inheritance does allow chaining like A is subclass of B which is subclass of C. If you call method it can walk through the classes and check which method to call (in reality it does not check classes one by one). Here B is subclass of A which is subclass of Object. Object happens to have (virtual) method GetHashCode - by overloading it in subclass. The Object method is hidden and (without tricks) cannot be used.
You should consider an alternative to calling Object.GetHashCode(). Here's why (from MSDN Library):
The default implementation of the
GetHashCode method does not guarantee
unique return values for different
objects. Furthermore, the .NET
Framework does not guarantee the
default implementation of the
GetHashCode method, and the value it
returns will be the same between
different versions of the .NET
Framework. Consequently, the default
implementation of this method must not
be used as a unique object identifier
for hashing purposes.