关于C#语言设计的小问题:))
如果我有这样的界面:
interface IFoo {
int Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
可以使用C#3.0自动实现的属性显式实现此类接口:
sealed class Foo : IFoo {
int IFoo.Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
但如果我在界面中有一个事件:
interface IFoo {
event EventHandler Event;
}
Run Code Online (Sandbox Code Playgroud)
并尝试使用类似字段的事件显式实现它:
sealed class Foo : IFoo {
event EventHandler IFoo.Event;
}
Run Code Online (Sandbox Code Playgroud)
我将得到以下编译器错误:
error CS0071: An explicit interface implementation of an event must use event accessor syntax
我认为类似字段的事件是自动实现属性的某种二元论.
所以我的问题是:这种限制的设计原因是什么?
我有一种情况,其中两个类(一个派生自另一个)都明确地实现了相同的接口:
interface I
{
int M();
}
class A : I
{
int I.M() { return 1; }
}
class B : A, I
{
int I.M() { return 2; }
}
Run Code Online (Sandbox Code Playgroud)
从派生类的实现I.M(),我想调用基类的实现,但我不知道如何做到这一点.到目前为止我尝试的是(在B级):
int I.M() { return (base as I).M() + 2; }
// this gives a compile-time error
//error CS0175: Use of keyword 'base' is not valid in this context
int I.M() { return ((this as A) as I).M() + 2; }
// this results in an …Run Code Online (Sandbox Code Playgroud) 请注意以下简单的源代码:
using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
namespace A
{
public static class Program
{
private const MethodAttributes ExplicitImplementation =
MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final |
MethodAttributes.HideBySig | MethodAttributes.NewSlot;
private const MethodAttributes ImplicitImplementation =
MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig;
private static Type EmitMyIntfType(ModuleBuilder moduleBuilder)
{
var typeBuilder = moduleBuilder.DefineType("IMyInterface",
TypeAttributes.NotPublic | TypeAttributes.Interface | TypeAttributes.Abstract);
typeBuilder.DefineMethod("MyMethod", MethodAttributes.Assembly | MethodAttributes.Abstract |
MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
typeof(void), new[] { typeof(int) });
return typeBuilder.CreateType();
}
public static void Main()
{
var …Run Code Online (Sandbox Code Playgroud) 在C#中,如果您有两个具有相同方法的基接口(例如,F()),则可以使用显式实现来执行不同的impl.对于F().这使得您可以根据当前的观点对待不同的对象:作为IMyInterface1或IMyInterface2.这在Java中可行吗?
在尝试ICollection<T>.IsReadOnly从Collection<T>类中覆盖属性的显式接口实现时,我遇到了一些文档,指出显式接口成员实现无法被覆盖,因为它们不能具有修饰符,如virtual或abstract.在MSDN上,他们甚至通过创建另一个由显式接口成员实现调用的抽象或虚拟成员来指定如何使显式接口成员实现可用于继承.到目前为止没问题.
但后来我想:为什么有可能在C#重写任何刚刚通过指定接口的显式实现接口成员明确?
例如,假设我有一个这样的简单接口,具有属性和方法:
public interface IMyInterface
{
bool AlwaysFalse { get; }
bool IsTrue(bool value);
}
Run Code Online (Sandbox Code Playgroud)
还有一个A显式实现接口的类,并且有一个Test()调用自己的接口成员实现的方法.
public class A : IMyInterface
{
bool IMyInterface.AlwaysFalse
{ get { return false; } }
bool IMyInterface.IsTrue(bool value)
{ return value; }
public bool Test()
{ return ((IMyInterface)this).AlwaysFalse; }
}
Run Code Online (Sandbox Code Playgroud)
如您所见,四个成员中没有一个是虚拟的或抽象的,所以当我定义这样的类时B:
public class B : A
{
public bool AlwaysFalse
{ get …Run Code Online (Sandbox Code Playgroud) c# language-features overriding interface explicit-implementation
举个例子:
public interface IFoo
{
IFoo Bar();
}
public class Foo : IFoo
{
public Foo Bar()
{
//...
}
IFoo IFoo.Bar() { return Bar(); } //Why is this necessary?
}
Run Code Online (Sandbox Code Playgroud)
为什么IFoo Bar()即使Foo转换为IFoo没有强制转换,隐式实现也是必要的?
当我定义包含只写属性的接口时:
public interface IModuleScreenData
{
string Name { set; }
}
Run Code Online (Sandbox Code Playgroud)
并试图(天真地)明确地实施它,并且该财产也有一个公开可用的getter:
public class ModuleScreen : IModuleScreenData
{
string IModuleScreenData.Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我收到以下错误:
错误'IModuleScreenData.Name.get'添加了在接口成员'IModuleScreenData.Name'中找不到的访问者
但是,在使用这种替代语法之后,或多或少会出现错误:
public class ModuleScreen : IModuleScreenData
{
public string Name { get; IModuleScreenData.set; }
}
Run Code Online (Sandbox Code Playgroud)
我没有编译,我想我想做的事情是不可能的.我是对的,还是有一些秘密的酱语法呢?
通常,我在这样的反射中访问一个方法:
class Foo
{
public void M () {
var m = this.GetType ().GetMethod ("M");
m.Invoke(this, new object[] {}); // notice the pun
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当M是显式实现时,这会失败:
class Foo : SomeBase
{
void SomeBase.M () {
var m = this.GetType ().GetMethod ("M");
m.Invoke(this, new object[] {}); // fails as m is null
}
}
Run Code Online (Sandbox Code Playgroud)
如何使用反射访问显式实现的方法?
那个头衔是满口的,不是吗?......
这是我正在尝试做的事情:
public interface IBar {
void Bar();
}
public interface IFoo: IBar {
void Foo();
}
public class FooImpl: IFoo {
void IFoo.Foo() { /* works as expected */ }
//void IFoo.Bar() { /* i'd like to do this, but it doesn't compile */ }
//so I'm forced to use this instead:
void IBar.Bar() { /* this would compile */ }
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,调用Bar()是不方便的:
IFoo myFoo = new FooImpl();
//myFoo.Bar(); /* doesn't compile */
((IBar)myFoo).Bar(); /* works, but it's not …Run Code Online (Sandbox Code Playgroud) 码:
public interface IFoo
{
void Bar();
}
public class FooClass : IFoo
{
/// <summary> ... </summary>
/// <seealso cref="?"/> //How do you reference the IFoo.Bar() method
public void Bar() { }
/// <summary> ... </summary>
/// <seealso cref="?"/> //How do you reference the standard Bar() method
void IFoo.Bar() { }
}
Run Code Online (Sandbox Code Playgroud)
我的猜测是:
<seealso cref="IFoo.Bar()"/> //Explicitly implemented interface method
<seealso cref="Bar()"/> //Standard method
Run Code Online (Sandbox Code Playgroud)
但是,我不确定.ECMA指南没有帮助区分,所以我想我正在寻找保证我的猜测是正确的.
c# ×10
interface ×5
.net ×4
reflection ×2
base-class ×1
events ×1
inheritance ×1
java ×1
overriding ×1
properties ×1
xml-comments ×1