继承 - 调用 child 方法而不是 parent
Inheritance - Invoke child methods instead of parent
很难解释为什么我会做我即将向您展示的事情,但他们有理由留在我这里。 (欢迎提出建议)。
我有一个 Functor,它在其输入上调用一个方法。
!请注意!仿函数实际上是一个扩展方法,因此必须有类型推断。
此外,我有一个带有 2 child 的抽象 class 和一个需要方法签名的接口。
示例代码如下所示:
public sealed class AbstractionTester
{
internal static void Run()
{
// The functor here accepts A type but in my original code its just a generic type.
// I wanted to keep it simple for this example only
Func<A, bool> func = a =>
{
a.CallMe(); //Displays "Error"
return true;
};
B obj = new B();
func(obj);
}
}
internal interface ICallMe<T>
where T : MyEntity
{
T CallMe();
}
//Just a class which holds data I would like to store about every object I have, for example: CreateDate
internal abstract class MyEntity
{ }
internal abstract class A : MyEntity, ICallMe<A>
{
//some other fields i would like to store..
// This method here must never be invoked
public A CallMe()
{
//throw new Exception();
Console.WriteLine("Error");
return this;
}
}
internal class B : A, ICallMe<B>
{
public new B CallMe()
{
Console.WriteLine("B");
return this;
}
}
internal class C : A, ICallMe<C>
{
public new C CallMe()
{
Console.WriteLine("C");
return this;
}
}
每次我调用 运行() 时,结果是 Error 出现在屏幕上。
我该怎么做才能强制我拥有的这个仿函数不会执行 parent class.
中的方法
Functor 永远不会收到 A 的实例,因为 A 是抽象的(我的意思是纯 A,而不是 A 的 child)
附加信息:
- 我必须在 class
B
和 C
中明确写出 CallMe
的 return 类型。我不能将它们更改为类型 A
.
- 我需要在仿函数中保留 A 的类型(或类似的东西),因为我需要推断某些代码延续的类型。
这是一个解决方案,无需将 public A CallMe()
定义为 virtual
。这样做的好处是 child 类 可以将他们的 CallMe()
定义为 new
,这样他们就可以 return B
或 C
。但它要求您可以使 类 public
而不是 internal
(否则您将得到 an error)。
使用动态调度调用实际的运行时类型而不是接口中声明的类型:
Func<A, bool> func = a => {
var runtimeType = (dynamic)a;
runtimeType.CallMe();
return true;
};
这有一个特定的语言功能;界面重新实现。
显式重新实现接口并使通用仿函数采用 ICallable<T>
:
internal class B : A, ICallMe<B>
{
B ICallable<B>.CallMe()
{
Console.WriteLine("B");
return this;
}
}
internal class C : A, ICallMe<C>
{
B ICallable<C>.CallMe()
{
Console.WriteLine("B");
return this;
}
}
你的函子应该是:
Func<T, bool> func = a => ...
并且 T
应该(在方法或 class 级别)限制为 ICallable<T>
。
更新:如果函子真的是一个扩展代码,我不确定是什么问题:
public static bool MyEnxtensionMethod<T>(T argument)
where T: ICallable<T>
{
argument.CallMe();
return true;
}
为什么你需要在任何地方保留 A
?
确保永远不会调用 A 的 CallMe
方法的最佳方法是让它 不存在。
internal abstract class MyEntity
{ }
internal abstract class A : MyEntity
{ }
现在永远无法按您的要求调用。
现在使接口协变:
internal interface ICallMe<out T>
where T : MyEntity
{
T CallMe();
}
然后把Func<A, bool>
改成Func<ICallMe<A>, bool>
public sealed class AbstractionTester
{
internal static void Run()
{
// The functor here accepts A type but in my original code its just a generic type.
// I wanted to keep it simple for this example only
Func<ICallMe<A>, bool> func = a =>
{
a.CallMe(); //Displays "B"
return true;
};
B obj = new B();
func(obj);
}
}
这真是奇怪的实现。为什么不使用 访客模式?
那么你可以这样做:
static void Main(string[] args)
{
Element a = new A();
Element b = new B();
Element c = new C();
ICallMe callMe = new CallMe();
a.accept(callMe);
b.accept(callMe);
c.accept(callMe);
}
下面的实现:
public interface ICallMe
{
void Visit(A a);
void Visit(B b);
void Visit(C c);
}
public class CallMe : ICallMe
{
public void Visit(A c)
{
Console.WriteLine("A");
}
public void Visit(B b)
{
Console.WriteLine("B");
}
public void Visit(C a)
{
Console.WriteLine("C");
}
}
interface Element
{
void accept(ICallMe visitor);
}
public class A : Element
{
public void accept(ICallMe visitor)
{
visitor.Visit(this);
}
}
public class B : Element
{
public void accept(ICallMe visitor)
{
visitor.Visit(this);
}
}
public class C : Element
{
public void accept(ICallMe visitor)
{
visitor.Visit(this);
}
}
很难解释为什么我会做我即将向您展示的事情,但他们有理由留在我这里。 (欢迎提出建议)。
我有一个 Functor,它在其输入上调用一个方法。
!请注意!仿函数实际上是一个扩展方法,因此必须有类型推断。
此外,我有一个带有 2 child 的抽象 class 和一个需要方法签名的接口。
示例代码如下所示:
public sealed class AbstractionTester
{
internal static void Run()
{
// The functor here accepts A type but in my original code its just a generic type.
// I wanted to keep it simple for this example only
Func<A, bool> func = a =>
{
a.CallMe(); //Displays "Error"
return true;
};
B obj = new B();
func(obj);
}
}
internal interface ICallMe<T>
where T : MyEntity
{
T CallMe();
}
//Just a class which holds data I would like to store about every object I have, for example: CreateDate
internal abstract class MyEntity
{ }
internal abstract class A : MyEntity, ICallMe<A>
{
//some other fields i would like to store..
// This method here must never be invoked
public A CallMe()
{
//throw new Exception();
Console.WriteLine("Error");
return this;
}
}
internal class B : A, ICallMe<B>
{
public new B CallMe()
{
Console.WriteLine("B");
return this;
}
}
internal class C : A, ICallMe<C>
{
public new C CallMe()
{
Console.WriteLine("C");
return this;
}
}
每次我调用 运行() 时,结果是 Error 出现在屏幕上。 我该怎么做才能强制我拥有的这个仿函数不会执行 parent class.
中的方法Functor 永远不会收到 A 的实例,因为 A 是抽象的(我的意思是纯 A,而不是 A 的 child)
附加信息:
- 我必须在 class
B
和C
中明确写出CallMe
的 return 类型。我不能将它们更改为类型A
. - 我需要在仿函数中保留 A 的类型(或类似的东西),因为我需要推断某些代码延续的类型。
这是一个解决方案,无需将 public A CallMe()
定义为 virtual
。这样做的好处是 child 类 可以将他们的 CallMe()
定义为 new
,这样他们就可以 return B
或 C
。但它要求您可以使 类 public
而不是 internal
(否则您将得到 an error)。
使用动态调度调用实际的运行时类型而不是接口中声明的类型:
Func<A, bool> func = a => {
var runtimeType = (dynamic)a;
runtimeType.CallMe();
return true;
};
这有一个特定的语言功能;界面重新实现。
显式重新实现接口并使通用仿函数采用 ICallable<T>
:
internal class B : A, ICallMe<B>
{
B ICallable<B>.CallMe()
{
Console.WriteLine("B");
return this;
}
}
internal class C : A, ICallMe<C>
{
B ICallable<C>.CallMe()
{
Console.WriteLine("B");
return this;
}
}
你的函子应该是:
Func<T, bool> func = a => ...
并且 T
应该(在方法或 class 级别)限制为 ICallable<T>
。
更新:如果函子真的是一个扩展代码,我不确定是什么问题:
public static bool MyEnxtensionMethod<T>(T argument)
where T: ICallable<T>
{
argument.CallMe();
return true;
}
为什么你需要在任何地方保留 A
?
确保永远不会调用 A 的 CallMe
方法的最佳方法是让它 不存在。
internal abstract class MyEntity
{ }
internal abstract class A : MyEntity
{ }
现在永远无法按您的要求调用。
现在使接口协变:
internal interface ICallMe<out T>
where T : MyEntity
{
T CallMe();
}
然后把Func<A, bool>
改成Func<ICallMe<A>, bool>
public sealed class AbstractionTester
{
internal static void Run()
{
// The functor here accepts A type but in my original code its just a generic type.
// I wanted to keep it simple for this example only
Func<ICallMe<A>, bool> func = a =>
{
a.CallMe(); //Displays "B"
return true;
};
B obj = new B();
func(obj);
}
}
这真是奇怪的实现。为什么不使用 访客模式?
那么你可以这样做:
static void Main(string[] args)
{
Element a = new A();
Element b = new B();
Element c = new C();
ICallMe callMe = new CallMe();
a.accept(callMe);
b.accept(callMe);
c.accept(callMe);
}
下面的实现:
public interface ICallMe
{
void Visit(A a);
void Visit(B b);
void Visit(C c);
}
public class CallMe : ICallMe
{
public void Visit(A c)
{
Console.WriteLine("A");
}
public void Visit(B b)
{
Console.WriteLine("B");
}
public void Visit(C a)
{
Console.WriteLine("C");
}
}
interface Element
{
void accept(ICallMe visitor);
}
public class A : Element
{
public void accept(ICallMe visitor)
{
visitor.Visit(this);
}
}
public class B : Element
{
public void accept(ICallMe visitor)
{
visitor.Visit(this);
}
}
public class C : Element
{
public void accept(ICallMe visitor)
{
visitor.Visit(this);
}
}