Say I have a base class TestBase where I define a virtual method TestMe()
class TestBase
{
public virtual bool TestMe() { }
}
Now I inherit this class:
class Test1 : TestBase
{
public override bool TestMe() {}
}
Now, using Reflection, I need to find if the method TestMe has been overriden in child class - is it possible?
What I need it for - I am writing a designer visualizer for type "object" to show the whole hierarchy of inheritance and also show which virtual methods were overridden at which level.
Given the type Test1, you can determine whether it has its own implementation declaration of TestMe:
typeof(Test1).GetMethod("TestMe").DeclaringType == typeof(Test1)
If the declaration came from a base type, this will evaluate false.
Note that since this is testing declaration, not true implementation, this will return true if Test1 is also abstract and TestMe is abstract, since Test1 would have its own declaration. If you want to exclude that case, add && !GetMethod("TestMe").IsAbstract
I was unable to get Ken Beckett's proposed solution to work. Here's what I settled on:
public static bool IsOverride(MethodInfo m) {
return m.GetBaseDefinition().DeclaringType != m.DeclaringType;
}
There are tests in the gist.
As #CiprianBortos pointed out, the accepted answer is not complete and will lead to a nasty bug in your code if you use it as-is.
His comment provides the magic solution GetBaseDefinition(), but there's no need to check the DeclaringType if you want a general-purpose IsOverride check (which I think was the point of this question), just methodInfo.GetBaseDefinition() != methodInfo.
Or, provided as an extension method on MethodInfo, I think this will do the trick:
public static class MethodInfoUtil
{
public static bool IsOverride(this MethodInfo methodInfo)
{
return (methodInfo.GetBaseDefinition() != methodInfo);
}
}
A simple solution which will also work for protected member and properties is as follows:
var isDerived = typeof(Test1 ).GetMember("TestMe",
BindingFlags.NonPublic
| BindingFlags.Instance
| BindingFlags.DeclaredOnly).Length == 0;
This is a repost of my answer here, which in turn had made references to this question.
A method that also works in some non trivial cases:
public bool Overrides(MethodInfo baseMethod, Type type)
{
if(baseMethod==null)
throw new ArgumentNullException("baseMethod");
if(type==null)
throw new ArgumentNullException("type");
if(!type.IsSubclassOf(baseMethod.ReflectedType))
throw new ArgumentException(string.Format("Type must be subtype of {0}",baseMethod.DeclaringType));
while(type!=baseMethod.ReflectedType)
{
var methods=type.GetMethods(BindingFlags.Instance|
BindingFlags.DeclaredOnly|
BindingFlags.Public|
BindingFlags.NonPublic);
if(methods.Any(m=>m.GetBaseDefinition()==baseMethod))
return true;
type=type.BaseType;
}
return false;
}
And a few ugly tests:
public bool OverridesObjectEquals(Type type)
{
var baseMethod=typeof(object).GetMethod("Equals", new Type[]{typeof(object)});
return Overrides(baseMethod,type);
}
void Main()
{
(OverridesObjectEquals(typeof(List<int>))==false).Dump();
(OverridesObjectEquals(typeof(string))==true).Dump();
(OverridesObjectEquals(typeof(Hider))==false).Dump();
(OverridesObjectEquals(typeof(HiderOverrider))==false).Dump();
(OverridesObjectEquals(typeof(Overrider))==true).Dump();
(OverridesObjectEquals(typeof(OverriderHider))==true).Dump();
(OverridesObjectEquals(typeof(OverriderNothing))==true).Dump();
}
class Hider
{
public virtual new bool Equals(object o)
{
throw new NotSupportedException();
}
}
class HiderOverrider:Hider
{
public override bool Equals(object o)
{
throw new NotSupportedException();
}
}
class Overrider
{
public override bool Equals(object o)
{
throw new NotSupportedException();
}
}
class OverriderHider:Overrider
{
public new bool Equals(object o)
{
throw new NotSupportedException();
}
}
class OverriderNothing:Overrider
{
}
According to this answer there could also be a simple way to check if a virtual method was overridden without to know the exact derived or base type using a test for the MethodAttributes.NewSlot attribute:
public static bool HasOverride(this MethodInfo method)
{
return (method.Attributes & MethodAttributes.Virtual) != 0 &&
(method.Attributes & MethodAttributes.NewSlot) == 0;
}
Together with another extension method
private const BindingFlags Flags = BindingFlags.NonPublic |
BindingFlags.Public | BindingFlags.Instance;
public static bool HasOverride(this Type type, string name, params Type[] argTypes)
{
MethodInfo method = type.GetMethod(name, Flags, null, CallingConventions.HasThis,
argTypes, new ParameterModifier[0]);
return method != null && method.HasOverride();
}
you could then simply call
bool hasOverride = GetType().HasOverride(nameof(MyMethod), typeof(Param1Type),
typeof(Param2Type), ...);
to check if MyMethod is overridden in a derived class.
As far as I've tested this, it seemed to work fine (on my machineā¢).
There is a better, safer and faster way to do it.
This technique makes sense if your class instance is going to have a long life and the IsOverridden check must be performed several times.
To solve this problem we can use a cache and C# delegates, much faster than reflection!
// Author: Salvatore Previti - 2011.
/// <summary>We need a delegate type to our method to make this technique works.</summary>
delegate int MyMethodDelegate(string parameter);
/// <summary>An enum used to mark cache status for IsOverridden.</summary>
enum OverriddenCacheStatus
{
Unknown,
NotOverridden,
Overridden
}
public class MyClassBase
{
/// <summary>Cache for IsMyMethodOverridden.</summary>
private volatile OverriddenCacheStatus pMyMethodOverridden;
public MyClassBase()
{
// Look mom, no overhead in the constructor!
}
/// <summary>
/// Returns true if method MyMethod is overridden; False if not.
/// We have an overhead the first time this function is called, but the
/// overhead is a lot less than using reflection alone. After the first time
/// this function is called, the operation is really fast! Yeah!
/// This technique works better if IsMyMethodOverridden() should
/// be called several times on the same object.
/// </summary>
public bool IsMyMethodOverridden()
{
OverriddenCacheStatus v = this.pMyMethodOverridden;
switch (v)
{
case OverriddenCacheStatus.NotOverridden:
return false; // Value is cached! Faaast!
case OverriddenCacheStatus.Overridden:
return true; // Value is cached! Faaast!
}
// We must rebuild cache.
// We use a delegate: also if this operation allocates a temporary object
// it is a lot faster than using reflection!
// Due to "limitations" in C# compiler, we need the type of the delegate!
MyMethodDelegate md = this.MyMethod;
if (md.Method.DeclaringType == typeof(MyClassBase))
{
this.pMyMethodOverridden = OverriddenCacheStatus.NotOverridden;
return false;
}
this.pMyMethodOverridden = OverriddenCacheStatus.Overridden;
return true;
}
/// <summary>Our overridable method. Can be any kind of visibility.</summary>
protected virtual int MyMethod(string parameter)
{
// Default implementation
return 1980;
}
/// <summary>Demo function that calls our method and print some stuff.</summary>
public void DemoMethod()
{
Console.WriteLine(this.GetType().Name + " result:" + this.MyMethod("x") + " overridden:" + this.IsMyMethodOverridden());
}
}
public class ClassSecond :
MyClassBase
{
}
public class COverridden :
MyClassBase
{
protected override int MyMethod(string parameter)
{
return 2011;
}
}
class Program
{
static void Main(string[] args)
{
MyClassBase a = new MyClassBase();
a.DemoMethod();
a = new ClassSecond();
a.DemoMethod();
a = new COverridden();
a.DemoMethod();
Console.ReadLine();
}
}
When you run this program as a console application, it will print:
MyClassBase result:1980 overridden:False
ClassSecond result:1980 overridden:False
COverridden result:2011 overridden:True
Tested with Visual Studio 2010, C# 4.0.
Should work also on previous versions, but it can be a little slower on C# less than 3.0 due to optimizations to delegates in the new releases, tests about this would be appreciated :)
However it will be still faster than using reflection!
public static bool HasOverridingMethod(this Type type, MethodInfo baseMethod) {
return type.GetOverridingMethod( baseMethod ) != null;
}
public static MethodInfo GetOverridingMethod(this Type type, MethodInfo baseMethod) {
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod;
return type.GetMethods( flags ).FirstOrDefault( i => baseMethod.IsBaseMethodOf( i ) );
}
private static bool IsBaseMethodOf(this MethodInfo baseMethod, MethodInfo method) {
return baseMethod.DeclaringType != method.DeclaringType && baseMethod == method.GetBaseDefinition();
}
Simple 1-liner based on this and this answers:
typeof(T).GetMember(nameof("Method")).OfType<MethodInfo>()
.Where(m => m.GetBaseDefinition().DeclaringType != m.DeclaringType);
Related
Is there a typedef equivalent in C#, or someway to get some sort of similar behaviour? I've done some googling, but everywhere I look seems to be negative. Currently I have a situation similar to the following:
class GenericClass<T>
{
public event EventHandler<EventData> MyEvent;
public class EventData : EventArgs { /* snip */ }
// ... snip
}
Now, it doesn't take a rocket scientist to figure out that this can very quickly lead to a lot of typing (apologies for the horrible pun) when trying to implement a handler for that event. It'd end up being something like this:
GenericClass<int> gcInt = new GenericClass<int>;
gcInt.MyEvent += new EventHandler<GenericClass<int>.EventData>(gcInt_MyEvent);
// ...
private void gcInt_MyEvent(object sender, GenericClass<int>.EventData e)
{
throw new NotImplementedException();
}
Except, in my case, I was already using a complex type, not just an int. It'd be nice if it were possible to simplify this a little...
Edit: ie. perhaps typedefing the EventHandler instead of needing to redefine it to get similar behaviour.
No, there's no true equivalent of typedef. You can use 'using' directives within one file, e.g.
using CustomerList = System.Collections.Generic.List<Customer>;
but that will only impact that source file. In C and C++, my experience is that typedef is usually used within .h files which are included widely - so a single typedef can be used over a whole project. That ability does not exist in C#, because there's no #include functionality in C# that would allow you to include the using directives from one file in another.
Fortunately, the example you give does have a fix - implicit method group conversion. You can change your event subscription line to just:
gcInt.MyEvent += gcInt_MyEvent;
:)
Jon really gave a nice solution, I didn't know you could do that!
At times what I resorted to was inheriting from the class and creating its constructors. E.g.
public class FooList : List<Foo> { ... }
Not the best solution (unless your assembly gets used by other people), but it works.
If you know what you're doing, you can define a class with implicit operators to convert between the alias class and the actual class.
class TypedefString // Example with a string "typedef"
{
private string Value = "";
public static implicit operator string(TypedefString ts)
{
return ((ts == null) ? null : ts.Value);
}
public static implicit operator TypedefString(string val)
{
return new TypedefString { Value = val };
}
}
I don't actually endorse this and haven't ever used something like this, but this could probably work for some specific circumstances.
Both C++ and C# are missing easy ways to create a new type which is semantically identical to an exisiting type. I find such 'typedefs' totally essential for type-safe programming and its a real shame c# doesn't have them built-in. The difference between void f(string connectionID, string username) to void f(ConID connectionID, UserName username) is obvious ...
(You can achieve something similar in C++ with boost in BOOST_STRONG_TYPEDEF)
It may be tempting to use inheritance but that has some major limitations:
it will not work for primitive types
the derived type can still be casted to the original type, ie we can send it to a function receiving our original type, this defeats the whole purpose
we cannot derive from sealed classes (and ie many .NET classes are sealed)
The only way to achieve a similar thing in C# is by composing our type in a new class:
class SomeType {
public void Method() { .. }
}
sealed class SomeTypeTypeDef {
public SomeTypeTypeDef(SomeType composed) { this.Composed = composed; }
private SomeType Composed { get; }
public override string ToString() => Composed.ToString();
public override int GetHashCode() => HashCode.Combine(Composed);
public override bool Equals(object obj) => obj is TDerived o && Composed.Equals(o.Composed);
public bool Equals(SomeTypeTypeDefo) => object.Equals(this, o);
// proxy the methods we want
public void Method() => Composed.Method();
}
While this will work it is very verbose for just a typedef.
In addition we have a problem with serializing (ie to Json) as we want to serialize the class through its Composed property.
Below is a helper class that uses the "Curiously Recurring Template Pattern" to make this much simpler:
namespace Typedef {
[JsonConverter(typeof(JsonCompositionConverter))]
public abstract class Composer<TDerived, T> : IEquatable<TDerived> where TDerived : Composer<TDerived, T> {
protected Composer(T composed) { this.Composed = composed; }
protected Composer(TDerived d) { this.Composed = d.Composed; }
protected T Composed { get; }
public override string ToString() => Composed.ToString();
public override int GetHashCode() => HashCode.Combine(Composed);
public override bool Equals(object obj) => obj is Composer<TDerived, T> o && Composed.Equals(o.Composed);
public bool Equals(TDerived o) => object.Equals(this, o);
}
class JsonCompositionConverter : JsonConverter {
static FieldInfo GetCompositorField(Type t) {
var fields = t.BaseType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy);
if (fields.Length!=1) throw new JsonSerializationException();
return fields[0];
}
public override bool CanConvert(Type t) {
var fields = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy);
return fields.Length == 1;
}
// assumes Compositor<T> has either a constructor accepting T or an empty constructor
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
while (reader.TokenType == JsonToken.Comment && reader.Read()) { };
if (reader.TokenType == JsonToken.Null) return null;
var compositorField = GetCompositorField(objectType);
var compositorType = compositorField.FieldType;
var compositorValue = serializer.Deserialize(reader, compositorType);
var ctorT = objectType.GetConstructor(new Type[] { compositorType });
if (!(ctorT is null)) return Activator.CreateInstance(objectType, compositorValue);
var ctorEmpty = objectType.GetConstructor(new Type[] { });
if (ctorEmpty is null) throw new JsonSerializationException();
var res = Activator.CreateInstance(objectType);
compositorField.SetValue(res, compositorValue);
return res;
}
public override void WriteJson(JsonWriter writer, object o, JsonSerializer serializer) {
var compositorField = GetCompositorField(o.GetType());
var value = compositorField.GetValue(o);
serializer.Serialize(writer, value);
}
}
}
With Composer the above class becomes simply:
sealed Class SomeTypeTypeDef : Composer<SomeTypeTypeDef, SomeType> {
public SomeTypeTypeDef(SomeType composed) : base(composed) {}
// proxy the methods we want
public void Method() => Composed.Method();
}
And in addition the SomeTypeTypeDef will serialize to Json in the same way that SomeType does.
Hope this helps !
With C# 10 you can now do
global using Bar = Foo
Which works like a typedef within the project.
I haven't tested it in depth, so there might be quirks.
I'm using it like
global using DateTime = DontUseDateTime
Where DontUseDateTime is a struct marked Obsolete, to force people to use NodaTime.
I think there is no typedef. You could only define a specific delegate type instead of the generic one in the GenericClass, i.e.
public delegate GenericHandler EventHandler<EventData>
This would make it shorter. But what about the following suggestion:
Use Visual Studio. This way, when you typed
gcInt.MyEvent +=
it already provides the complete event handler signature from Intellisense. Press TAB and it's there. Accept the generated handler name or change it, and then press TAB again to auto-generate the handler stub.
C# supports some inherited covariance for event delegates, so a method like this:
void LowestCommonHander( object sender, EventArgs e ) { ... }
Can be used to subscribe to your event, no explicit cast required
gcInt.MyEvent += LowestCommonHander;
You can even use lambda syntax and the intellisense will all be done for you:
gcInt.MyEvent += (sender, e) =>
{
e. //you'll get correct intellisense here
};
You can use an open source library and NuGet package called LikeType that I created that will give you the GenericClass<int> behavior that you're looking for.
The code would look like:
public class SomeInt : LikeType<int>
{
public SomeInt(int value) : base(value) { }
}
[TestClass]
public class HashSetExample
{
[TestMethod]
public void Contains_WhenInstanceAdded_ReturnsTrueWhenTestedWithDifferentInstanceHavingSameValue()
{
var myInt = new SomeInt(42);
var myIntCopy = new SomeInt(42);
var otherInt = new SomeInt(4111);
Assert.IsTrue(myInt == myIntCopy);
Assert.IsFalse(myInt.Equals(otherInt));
var mySet = new HashSet<SomeInt>();
mySet.Add(myInt);
Assert.IsTrue(mySet.Contains(myIntCopy));
}
}
Here is the code for it, enjoy!, I picked that up from the dotNetReference
type the "using" statement inside the namespace line 106
http://referencesource.microsoft.com/#mscorlib/microsoft/win32/win32native.cs
using System;
using System.Collections.Generic;
namespace UsingStatement
{
using Typedeffed = System.Int32;
using TypeDeffed2 = List<string>;
class Program
{
static void Main(string[] args)
{
Typedeffed numericVal = 5;
Console.WriteLine(numericVal++);
TypeDeffed2 things = new TypeDeffed2 { "whatever"};
}
}
}
I'd do
using System.Collections.Generic;
global using CustomerList = List<Customer>;
For non-sealed classes simply inherit from them:
public class Vector : List<int> { }
But for sealed classes it's possible to simulate typedef behavior with such base class:
public abstract class Typedef<T, TDerived> where TDerived : Typedef<T, TDerived>, new()
{
private T _value;
public static implicit operator T(Typedef<T, TDerived> t)
{
return t == null ? default : t._value;
}
public static implicit operator Typedef<T, TDerived>(T t)
{
return t == null ? default : new TDerived { _value = t };
}
}
// Usage examples
class CountryCode : Typedef<string, CountryCode> { }
class CurrencyCode : Typedef<string, CurrencyCode> { }
class Quantity : Typedef<int, Quantity> { }
void Main()
{
var canadaCode = (CountryCode)"CA";
var canadaCurrency = (CurrencyCode)"CAD";
CountryCode cc = canadaCurrency; // Compilation error
Concole.WriteLine(canadaCode == "CA"); // true
Concole.WriteLine(canadaCurrency); // CAD
var qty = (Quantity)123;
Concole.WriteLine(qty); // 123
}
The best alternative to typedef that I've found in C# is using. For example, I can control float precision via compiler flags with this code:
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
Unfortunately, it requires that you place this at the top of every file where you use real_t. There is currently no way to declare a global namespace type in C#.
Since the introduction of C# 10.0, we now have the global using directive.
global using CustomerList = System.Collections.Generic.List<Customer>;
This introduces CustomerList as alias of List<Customer> on a global scope (throughout the whole project and all references to it).
Though I would have liked to be able to limit its scope (say for instance 'internal using') this does actually do a terrific job of fulfilling a typedef variant in C#.
I just need to know if there's a smart way to detect if a particular Type method has overloads or not.
At the moment I'm iterating through methods and searching for DeclaringType+Name ambiguity...but I think it's a bit lame :)
The overload is what happens when you have two methods with the same name but different signatures.
So if we can the method is override by check method name whether more than one.
I would create an extension method IsOverloads to make it.
use the IsOverloads method need to provide at least two parameter
the class Type.
check method name
Using reflection to gets method information from the class, then check the method name greater than one means the method is overload.
public static class Ext {
public static bool IsOverloads(this Type type,string methodName)
{
return IsOverloads(type, methodName, BindingFlags.Public | BindingFlags.Instance);
}
public static bool IsOverloads(this Type type,
string methodName,
BindingFlags flags)
{
var info = type.GetMethods(flags);
return info.Where(o1 => o1.Name == methodName).Count() > 1;
}
}
Here is a simple
public class Program
{
public void Test() { }
public void Test(int a) { }
public void TestNo(int a) { }
public static void Main()
{
Console.WriteLine(typeof(Program).IsOverloads("Test")); //True
Console.WriteLine(typeof(Program).IsOverloads("TestNo")); //false
}
}
c# online
I've a project where I am extensively using the generic C# dictionary. I require composite keys, so I've been using tuples as keys. At some point I was wondering whether it would be beneficial to use a custom class which caches the hash code:
public class CompositeKey<T1, T2> : Tuple<T1, T2>
{
private readonly int _hashCode;
public CompositeKey(T1 t1, T2 t2) : base(t1, t2)
{
_hashCode = base.GetHashCode();
}
public new int GetHashCode()
{
return _hashCode;
}
}
I used new instead of override because I thought it would not make a difference for this test, since I was defining the dictionary using the concrete type:
var dict = new Dictionary<CompositeKey<string, int>, int>();
I noticed, however, that my custom GetHashCode method is not called at all. When I changed new to override it got called as expected.
Can somebody explain why the hidden GetHashCode method is not called? I would expect this behavior if I would define the dictionary like this
var dict = new Dictionary<Tuple<string, int>, int>();
but not if I specify the CompositeKey type explicitly as in my example.
P.S. I know that hiding the GetHashCode method is probably not a good idea.
Can somebody explain why the hidden GetHashCode method is not called?
I would expect this behavior if I would define the dictionary like
this
To be able to call CompositeKey.GetHashCode method, one must have the reference of the instance of CompositeKey typed as CompositeKey in compile time.
But codebase of Dictionary<TKey,TValue> isn't aware of your CompositeKey class(obviously). All it knows is TKey(generic type parameter) which is as equivalent as having System.Object without any constraints. Because you can't call any methods of T other than which is declared in System.Object without a constraint.
So, Dictionary ends up calling Object.GetHashCode which isn't overridden in your class --and thus it is not called.
The overload resolution for method calls in generic types happens when the unbound generic type (e.g. Dictionary<TKey, TValue>) is compiled, not when a closed type (e.g. Dictionary<CompositeKey<string, int>, int>) is constructed.
Since there is no constraint on TKey in Dictionary<,>, the only overload of GetHashCode() available is object.GetHashCode(). Constructing a type where there is a better overload of GetHashCode() doesn't change the initial overload resolution.
It is not only restricted to methods hidden with new. The same happens with overloaded methods:
class Generic<T>
{
public bool Equal(T t1, T t2)
{
return t1.Equals(t2);
}
}
class X : IEquatable<X>
{
public override bool Equals(object obj)
{
Console.WriteLine("object.Equals");
return true;
}
public bool Equals(X other)
{
Console.WriteLine("IEquatable.Equals");
return true;
}
}
The X.Equals(X) overload will never be used
var test = new Generic<X>();
test.Equal(new X(), new X());
// prints "object.Equals"
Just to elaborate on the previous answers. The problem with new is that it ONLY overrides the method IF the consumer is directly operating on the class (in this case your CompositeKey class.) Any call on any base class that your CompositeKey derives from will NOT call your new member.
So if in the following:
CompositeKey.GetHashCode() <--- Will call your new method.
Tuple.GetHashCode() <--- Will not call your new method.
Object.GetHashCode() <--- Will not call your new method.
As previous answers have highlighted, because EqualityComparer (the class Dictionary uses) specifies that T is a non-constrained generic, then the compiler will only support the lowest common denominator for all T that could be passed to it, which is the methods directly on Object.
Therefore the call is effectively: ((Object)key).GetHashCode(). From above you can see that this will not call your new method.
It is because of the type constraints on generics. Here is a simplified program to show the problem.
public class Program
{
public static void Main(string[] args)
{
var bar = new Bar();
TestMethod(bar);
TestMethod2(bar);
}
public static void TestMethod<T>(T obj) where T : Foo
{
obj.Test();
obj.Test2();
}
public static void TestMethod2<T>(T obj) where T : Bar
{
obj.Test();
obj.Test2();
}
}
public class Foo
{
public virtual void Test()
{
Debugger.Break();
}
public virtual void Test2()
{
Debugger.Break();
}
}
public class Bar : Foo
{
public new void Test()
{
Debugger.Break();
}
public override void Test2()
{
Debugger.Break();
}
}
In TestMethod() you hit the breakpoint in Foo.Test() and Bar.Test2() but in TestMethod2() you hit the breakpoint in Bar.Test() and Bar.Test2(), this is because in the first method you are constrained to type Foo or lower so when the compiler compiles it binds to the call on Foo, it is the same as if the function was written as
public static void TestMethod<T>(T obj)
{
((Foo)obj).Test(); //You would expect this to call Foo.Test() b\c of shadowing
((Foo)obj).Test2(); //You would expect this to call Bar.Test2() b\c of overloading
}
Now, on to your problem, the comparer that is being used is written as
[Serializable]
internal class ObjectEqualityComparer<T>: EqualityComparer<T>
{
[Pure]
public override bool Equals(T x, T y) {
if (x != null) {
if (y != null) return x.Equals(y);
return false;
}
if (y != null) return false;
return true;
}
[Pure]
public override int GetHashCode(T obj) {
if (obj == null) return 0;
return obj.GetHashCode();
}
//...
}
There is no constraint on T so those two methods are behaving as if they are written as
public override bool Equals(T x, T y) {
if (x != null) {
if (y != null) return ((object)x).Equals(y);
return false;
}
if (y != null) return false;
return true;
}
[Pure]
public override int GetHashCode(T obj) {
if (obj == null) return 0;
return ((object)obj).GetHashCode();
}
That is why your function is only called when you overrode it and not when you shadowed it.
I want to write a method that will analyze custom attributes of any method (with any number of arguments and any return type) knowing only method info.
This function will check if method has specific Attribute. like this: var tmp = methodInfo.GetCustomAttributes(typeof(LineItemAttribute),false); and if it has such attribute It will execute it.And I want to make call of that function really easy to use. So, in example there are three methods and method GetMethodAttributes that I want to call.
class Test
{
public static void Main()
{
}
public void Test1(){}
public void Test2(int a){}
public void Test3(object a, string c, Boolean d);
public void GetMethodAttributes(MethodInfo mi) {}
}
Ideally I want to write something like that
public static void Main()
{
var t = new Test();
GetMethodAttributes(t.Test1);
GetMethodAttributes(t.Test2);
GetMethodAttributes(t.Test3);
}
I don't want to use string representation of the method names as method names may change, like that:
MethodInfo info = type.GetMethod(name);
Do I have any options? Basically I need a way to use delegates for functions with different sinatures
As Chris Sinclair pointed out in the comment above; you can use a delegate without using reflection or expression trees to get the MethodInfo. The downside is that the compiler is not able to infer the generic parameter so you have to specify the delegate type to match the signature of the given method like this:
public class Test
{
public static void Main()
{
var t = new Test();
CheckMethodAttributes<Action>(t.Test1);
CheckMethodAttributes<Action<int>>(t.Test2);
CheckMethodAttributes<Action<object, string, bool>>(t.Test3);
}
public void Test1() { }
public void Test2(int a) { }
public void Test3(object a, string c, bool d) { }
public static void CheckMethodAttributes<T>(T func)
{
MethodInfo method = new MethodOf<T>(func);
// Example attribute check:
var ignoreAttribute = method.GetAttribute<IgnoreAttribute>();
if (ignoreAttribute != null)
{
// Do something here...
}
}
}
This uses two utility classes, the MethodOf<T> for extracting the MethodInfo from the given Delegate and some AttributeUtils to get strongly typed custom attribute retrieval:
public static class AttributeUtils
{
public static bool HasAttribute<TAttribute>(this MemberInfo member, bool inherit = true)
where TAttribute : Attribute
{
return member.IsDefined(typeof(TAttribute), inherit);
}
public static TAttribute GetAttribute<TAttribute>(this MemberInfo member, bool inherit = true)
where TAttribute : Attribute
{
return member.GetAttributes<TAttribute>(inherit).FirstOrDefault();
}
public static IEnumerable<TAttribute> GetAttributes<TAttribute>(this MemberInfo member, bool inherit = true)
where TAttribute : Attribute
{
return member.GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>();
}
}
public class MethodOf<T>
{
public MethodOf(T func)
{
var del = func as Delegate;
if (del == null) throw new ArgumentException("Cannot convert func to Delegate.", "func");
Method = del.Method;
}
private MethodInfo Method { get; set; }
public static implicit operator MethodOf<T>(T func)
{
return new MethodOf<T>(func);
}
public static implicit operator MethodInfo(MethodOf<T> methodOf)
{
return methodOf.Method;
}
}
You can do something like this using Expression Trees, where you pass the method via a lambda expression. You do still need to pass stub values for the parameters, however. For a good example of this in action, check out the source code for Moq, which uses this pattern extensively for setting up mock behaviors for unit testing. Just note that this is not a trivial thing to set up. If you need something relatively quick and dirty, your best bet is probably string names with a good refactoring tool and/or automated tests to help deal with the renaming issues.
I have a generic class. It has 2 constructors. Those are widely used in my organization's codebase.
class MyClass<T> {
MyClass() { ... }
MyClass(T defaultValue) { ... }
}
I would like to add some functionality but keep backward-compatible. So I would like to introduce a new boolean optional parameter to each constructor:
class MyClass<T> {
MyClass(bool someFlag = false) { ... }
MyClass(T defaultValue, bool someFlag = false) { ... }
}
However, I already have a heap of usages out there in which T is boolean and a default value is passed:
class Usage {
MyClass<bool> Booly = new MyClass<bool>(false);
}
Now, according to the laws of overload preference - the compiler is tying all such constructor usages to the overload accepting someFlag, since typed methods "know better". While making perfect sense in most cases, this is obviously breaking my backward-compatibility.
My question is simple: Is there a language feature available for me to override the default laws of overload preference, and define the old generic overload as the preferred one, so that I don't have to change all such usages?
Of course, a drawback of this design is that whenever I would want to call the first overload (with only the someFlag parameter) - I would have to specify a named parameter as per C# 4 specifications.
Suggestions for other designs are also welcome, but please try to answer my question first :).
In general? No.
A specific... "workaround"... which might be acceptable in your case? Make the optional parameter a bool?, not a bool.
new MyClass<bool>(false) will call your defaultValue overload.
new MyClass<bool>(someFlag: false) will call the other overload.
That said, if you have any existing new MyClass<bool?>(false) calls, this will change them over instead.
You can overcome this by creating an class specifically for making your flags not be bools:
public struct FakeBool
{
private readonly bool val;
private FakeBool(bool val) { this.val = val; }
public static implicit operator bool(FakeBool f) { return f.val; }
public static implicit operator FakeBool(bool f) { return new FakeBool(f); }
}
public MyClass(FakeBool someFlag = default(FakeBool)) { ... }
public MyClass(T defaultValue, FakeBool someFlag = default(FakeBool)) { ... }
var b2 = new MyClass<bool>(true); // calls two-argument constructor
var b1 = new MyClass<bool>(someFlag: true); // calls one-argument constructor
but this is getting silly. (Also, I can't figure out how to get a default value of true - any ideas, anyone?)
Assuming you can have an Initialize() type method that you can call from each constructor, your best bet is to have three constructors:
MyClass() { Initialize(null, false); }
MyClass(T default, bool someFlag = false) { Initialize(default, someFlag); }
MyClass(bool someFlag)
{
if (typeof(T) == typeof(bool)) Initialize(someFlag, false);
else Initialize(null, someFlag);
}
private Initialize(T default, bool someFlag)
{
// Do whatever
}