- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想创建一个Func
,它是一些派生类的base.Equals
方法的双参数封装。 Func
的一个参数是调用 base.Equals
的实例,而 Func
的另一个参数被传递到 base.Equals
。我不能对基类提出要求,但我可以对派生类提出一些要求。例如,我可以要求派生类公开 base.Equals
。
如果关键字 base
可以像关键字 this
一样使用,这将很容易,但事实并非如此。在下面查看我失败的尝试。
using System;
namespace MyNamespace {
class BaseClass { }
class DerivedClass : BaseClass, IEquatable<DerivedClass> {
Func<DerivedClass, DerivedClass, bool> baseEquals;
DerivedClass() {
DerivedClass referenceToThis = this;
BaseClass referenceToBase = referenceToThis.base; // doesn't compile
this.baseEquals = (x, y) => x.Equals(y);
}
public bool Equals(DerivedClass that) => this.baseEquals(this, that);
}
}
以我目前对C#的理解,我认为想做的事情是不允许的。
Is there C# that has the same semantics as my example but is valid?
If not, how close can one get to this example? That is, to what extent can the
base.Equals
method be encapsulated?
编辑以添加示例
using System;
using FluentEquality.Common.EqualityCompareres;
namespace MyNamespace {
class MyProgram {
static void Main(string[] args) {
var instance0 = new LeafClass(0);
var instance1 = new LeafClass(1);
var baseEqualsMethod = SomeMagicalMethodYetToBeDefined(instance0.BaseEqualsMethod, instance0.BaseGetHashCodeMethod);
equalityComparer.Equals(instance0, instance1); // should output: BaseClass 0
equalityComparer.Equals(instance1, instance0); // should output: BaseClass 1
Console.ReadKey();
}
}
class BaseClass {
protected int Id;
public BaseClass(int id) { this.Id = id; }
public override bool Equals(object obj) { Console.WriteLine(nameof(BaseClass) + " " + Id); return false; }
public override int GetHashCode() => base.GetHashCode();
}
class DerivedClass : BaseClass {
public DerivedClass(int id) : base(id) { }
public override bool Equals(object obj) { Console.WriteLine(nameof(DerivedClass) + " " + Id); return false; }
public override int GetHashCode() => base.GetHashCode();
public Func<object, bool> BaseEqualsMethod => base.Equals;
public Func<int> BaseGetHashCodeMethod => base.GetHashCode;
}
class LeafClass : DerivedClass {
public LeafClass(int id) : base(id) { }
public override bool Equals(object obj) { Console.WriteLine(nameof(LeafClass) + " " + Id); return false; }
public override int GetHashCode() => base.GetHashCode();
}
}
最佳答案
因此,我的另一个答案存在致命缺陷,因为它存在与反射相同的问题 - 无论您尝试调用哪种方法,都会调用覆盖的方法。
以下是使用发现的技术的示例 here创建一个动态方法,确实允许您指定要调用哪个重写方法。这种方法的好处是您不需要类来公开基方法,事实上,您根本不需要修改类。
class BaseClass
{
public override bool Equals(object other)
{
Console.WriteLine("BaseClass");
return false;
}
}
class DerivedClass
{
public bool Equals(DerivedClass other)
{
Console.WriteLine("DerivedClass Equals");
return true;
}
public override bool Equals(object other)
{
Console.WriteLine("DerivedClass Object Equals");
return true;
}
}
static class MyComparerThing<TParentType>
{
public static bool Equals(TParentType left, TParentType right) => MyComparerThing<TParentType, TParentType, object>.Equals(left, right);
}
static class MyComparerThing<TParentType, TOnType>
{
public static bool Equals(TOnType left, TOnType right) => MyComparerThing<TParentType, TOnType, object>.Equals(left, right);
}
static class MyComparerThing<TParentType, TOnType, TCompareType>
{
static Func<TOnType, TOnType, bool> baseEquals;
static MyComparerThing()
{
DynamicMethod dm = new DynamicMethod("BaseFoo", typeof(bool), new Type[] { typeof(TOnType), typeof(TOnType) }, typeof(TOnType));
ILGenerator gen = dm.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
var method = typeof(TParentType).GetMethod("Equals", new[] { typeof(TCompareType) });
gen.Emit(OpCodes.Call, method);
gen.Emit(OpCodes.Ret);
baseEquals = (Func<TOnType, TOnType, bool>)dm.CreateDelegate(typeof(Func<TOnType, TOnType, bool>));
}
public static bool Equals(TOnType left, TOnType right) => baseEquals(left, right);
}
使用以下内容进行测试:
void Main()
{
var a = new DerivedClass();
var b = new DerivedClass();
//The generic parameters in order are:
//1. The type which implements the desired method
//2. The type of the arguments (a and b)
//3. The parameter argument of the method (object vs DerivedClass)
//The following three are equivelant, using 'default' generic arguments
MyComparerThing<DerivedClass>.Equals(a, b);
MyComparerThing<DerivedClass, DerivedClass>.Equals(a, b);
MyComparerThing<DerivedClass, DerivedClass, object>.Equals(a, b);
//This will print the method declared in BaseClass. a and b are still DerivedClass instances. This is the one you're wanting to use
MyComparerThing<BaseClass, DerivedClass>.Equals(a, b);
//This will print the method declared in DerivedClass, with the DerivedClass overload
MyComparerThing<DerivedClass, DerivedClass, DerivedClass>.Equals(a, b);
//This will print the method declared in DerivedClass, with the object overload
MyComparerThing<DerivedClass, DerivedClass, object>.Equals(a, b);
}
打印:
DerivedClass Object Equals
DerivedClass Object Equals
DerivedClass Object Equals
BaseClass
DerivedClass Equals
DerivedClass Object Equals
我选择使用泛型来决定调用哪个覆盖 - 但可以更改此设置以从其他地方提取信息,或者硬编码。如果你想总是调用基本方法,你需要修改上面的内容,按照 typeof(TOnType).BaseType.GetMethod("Equals", ....)
关于c# - 在 C# 中模拟基数分配有多接近,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37266637/
正如标题所说,我需要制作一个函数,在二进制补码中的 2 个碱基、DEC 和 HEX 之间进行转换。该值使用的位数从一开始就已知。 在深入研究之后,我发现了以下算法: 给定一个 DEC 中的数字。 获取
我的用户文档具有以下格式: { userId: "", userAttributes: [ "", "", ... ""
根据这个: Selectivity is the value between 0 and 1, and it is the fraction of rows returned after applyi
这个词有它 FillChar 是用相同值的字节填充内存补丁的最快方法(不是零,因为有 ZeroMemory),但是是否有等效于用相同的序列填充内存(四字节)整数或基数?像 FillInt 或 Fill
我正在努力寻找建模 1 : 0,1 关系的最佳方法(“可能有一个”或“最多有一个”)。我相信这被称为 Z 基数。 例如,假设我有两个类 Widget和 WidgetTest .并非所有 Widget
我使用parseInt找到了一个片段;它用于获取窗口高度。 这是代码: parseInt($(window).height(), 20); 我很困惑为什么使用 20 作为第二个参数。为什么不是 10
要将十进制数转换为基数 2,我使用: int base2 = 10; Convert.ToString(base2, 2); 输出:1010 但是我怎么能做相反的事情呢?即: 输入:1010输出:10
这是一张真实 table 的再现。假设我有这段代码: CREATE TABLE `testTable` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
由于十六进制(基数 16)使用 0-9A-F,并且(我在这里假设)基数 17 使用 0-9A-G,依此类推。什么符号用过一次0-9A-Z都用完了。 最佳答案 你的问题没有标准答案。 “Base 36”
我正在寻找支持 radix 的浏览器列表Number.toString() 中的参数在 JavaScript 中。全部执行toString ,但我找不到他们是否都支持 radix toString 的
这个问题已经有答案了: What is the radix parameter in Java, and how does it work? (6 个回答) 已关闭 5 年前。 public clas
为什么 (73).toString(36) 返回 21 而 (0.73).toString(36) 返回 0。 qa2voha2volfpsnhmyhqia4i 而不是 0.21? 最佳答案 这是因为
我目前正在研究数据库,我看到 degree 和 cardinality 用作相同的术语,或在某些其他学位定义为否。关系中涉及的实体的数量,并进一步分类为一元、二元和三元。 某些放置度数定义为关系类型的
UML(统一建模语言)中的运算符*和运算符0..*有什么区别? 我看到了这两个基数运算符,但是现在我不必使用哪个基数运算符了。 最佳答案 符号“*”是“0 .. *”的快捷方式。在这种情况下使用的正确
我有位于目录“someApp”中的 Angular 应用程序。网址是 http://example-domain/someApp/#/对于一些带有路径的状态 url 是:http://example-
我想一劳永逸地知道如何编写 UML 基数,因为我经常不得不讨论它们(因此非常欢迎证据和来源:) 如果我想解释一下 Mother可以有几个Child任但是 Child有一个而且只有一个 Mother ,
进行字符算术时,规则是以 10 为基数还是以 8 为基数进行计算?我的书上说'A' = 101(基数为8)或65(基数为10),但是当我将基数为8的字符值插入到我的书给出的关于说明这一点的示例中时,我
该程序是将 4 进制数转换为 2 进制数,并且应该就地完成 #include #include void shiftr(char num[],int i) { memmove(num+i,n
这个问题已经有答案了: JavaScript parseInt is giving me wrong number, what I'm doing wrong? [duplicate] (1 个回答)
我遇到了一个小错误,它似乎表明当您传入图像数据作为其源时,在图像完全加载之前调用了 onload 函数。 这是 HTML 这是 JavaScript: var can
我是一名优秀的程序员,十分优秀!