Calls within defining library do not honor interface
See original GitHub issuePreamble
- Fody 6.0.0
- Equals.Fody 4.0.0
- MSBuild 16
Describe the issue
When a modified type is used within the library, calls with that type are not rewritten honoring the interface. It’s not a major problem for those well versed in Fody, but for another developer coming along and learning it would be unexpected.
Minimal Repro
FodyWeavers.xml packages.config, and csproj excluded. Was targeting .NET 4.6.2
Program.cs
using System;
namespace DelMe.FodyEquals
{
using LibraryThatUsesEquatableAtCompileTime;
class Program
{
static void Main(string[] args)
{
if (new TypeUnderTest() is IEquatable<TypeUnderTest>)
{
Console.WriteLine("It is indeed equatable");
}
EquatableUser.DoSomething(new TypeUnderTest());
}
}
[Equals]
class TypeUnderTest
{
public int Number { get; private set; }
public static bool operator ==(TypeUnderTest left, TypeUnderTest right) => Operator.Weave(left, right);
public static bool operator !=(TypeUnderTest left, TypeUnderTest right) => Operator.Weave(left, right);
}
}
Class1.cs
using System;
namespace LibraryThatUsesEquatableAtCompileTime
{
public static class EquatableUser
{
public static void DoSomething(object obj)
{
throw new NotImplementedException("We want it to be always used as IEquatable");
}
// For additional testing, since determining between this and the other method might be ambiguous
//public static void DoSomething<T>(IEquatable<T> equatable)
//{
//throw new NotImplementedException("We expect the most specific method to be used, normal code would use the below method");
//}
public static void DoSomething<T>(T item)
where T : IEquatable<T>
{
}
}
}
Make an effort to fix the bug
Feel free to assign to me if you feel strongly about the effort rule and I’ll add it to my backlog 😃
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (5 by maintainers)
Top Results From Across the Web
GacIdentityPermission Class (System.Security.Permissions)
Code Access Security (CAS) has been deprecated across all versions of .NET Framework and .NET. Recent versions of .NET do not honor CAS...
Read more >What Is Code Replacement Customization? - MATLAB & Simulink
The ability to include tokens is not available from the Code Replacement Tool. See Specify build information in Define Code Replacement Library ......
Read more >Response Codes and Error Codes
The unique identifier that attempts to define the field in error, when available. If an error is not associated with a specific field,...
Read more >Chapter 1 Introduction to the API
A SunSoft goal is to define the Architectural Interfaces of Solaris. ... Static libraries do not provide an interface, they provide only an...
Read more >Raw responses
Status Raw acquirer response Description/Instruction
Refused 05: Do not honor (Decline Card Inv) Invalid gift card.
Refused 05: Do not honor (Decline InactiveBAL=0.00) Inactive gift...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@ndrwrbgs still interested in changing this? IMO equality is a perfect candidate for a Roslyn source generator like e.g. this: https://github.com/diegofrata/Generator.Equals, this will not have such side effects.
Note that the “harder solution” won’t be possible to implement correctly for all cases.
You’d have to reimplement Roslyn’s overload resolution (which is a major pain point in the compiler already), while having less information about the code. For instance, you wouldn’t be able to detect when a user forces a particular overload with
EquatableUser.DoSomething((object)new TypeUnderTest());
as that explicit(object)
cast is made implicit in IL. And that’s only one example of a problem, there are more.Adding a dummy
IEquatable<T>
implementation is the better approach.