考虑代码:
class ChildClass : BaseClass {
public void Method1() {} //some other method
}
abstract class BaseClass : IChildInterface {
public
virtual //<- If we add virtual so that this method can be overridden by ChildClass, we get StackOverflowException and DoWork() implementation in IChildInterface is never called.
void DoWork() {
//base class specific implmentation
((IChildInterface)this).DoWork(); //call into default implementation provided by IChildInterface
}
}
interface IChildInterface : IBaseInterface {
void IBaseInterface.DoWork() {
//implmentation
}
}
interface IBaseInterface {
void DoWork(); …
Run Code Online (Sandbox Code Playgroud) 我有几个接口(IMapFrom
和IMapTo
),可以让我简化AutoMapper
配置。每个接口都有MapTo
和MapFrom
方法的默认实现。我有一个单独的MappingProfile
类,它使用反射来查找所有实现类,并调用它们的映射创建。
上述类看起来像这样:
public interface IMapFrom<T>
{
void MapFrom(Profile profile) => profile.CreateMap(typeof(T), GetType());
}
public interface IMapTo<T>
{
void MapTo(Profile profile) => profile.CreateMap(GetType(), typeof(T));
}
public class MappingProfile : Profile
{
public MappingProfile()
{
ApplyMappingsFromAssembly(Assembly.GetExecutingAssembly());
}
private void ApplyMappingsFromAssembly(Assembly assembly)
{
var types = assembly.GetExportedTypes()
.Where(t => t.GetInterfaces().Any(i =>
i.IsGenericType && (i.GetGenericTypeDefinition() == typeof(IMapFrom<>) ||
i.GetGenericTypeDefinition() == typeof(IMapTo<>))))
.ToList();
foreach (var type in types)
{
var instance = Activator.CreateInstance(type); …
Run Code Online (Sandbox Code Playgroud) c# reflection system.reflection c#-8.0 default-interface-member
在编写 C# 时,我倾向于编写大量实现IEquatable<T>
、IComparable<T>
或两者的值类型对象。
为了这个建议,让我们假设我正在编写一个虚构的结构,用Int256
可等值和可比较值语义调用;例如:
public readonly struct Int256 : IEquatable<Int256>, IComparable<Int256>, IComparable
{
public bool Equals(Int256 other)
{
// TODO : is this equal to other?
}
public int CompareTo(Int256 other)
{
// TODO : how does this compare to other?
}
public int CompareTo(object? obj)
{
if (obj is null) return 1;
if (obj is not Int256 int256) throw new ArgumentException("Obj must be of type Int256.");
return CompareTo(int256);
}
public static bool operator …
Run Code Online (Sandbox Code Playgroud) 在 C# 8.0 中,我们有一个新功能,可以在接口中提供默认方法实现,该方法也可以被其实现类覆盖。
我们曾经使用带有实例方法的抽象类来为其所有实现类提供通用功能。
现在我可以将那些具有实例方法的抽象类替换为具有 C# 8.0 中的默认方法实现的接口吗?
我在 VS 16.5.1 上的控制台应用程序 .net core 3.1 中有这样的代码和平:
namespace DefaultInterfaceTest
{
class Program
{
static void Main(string[] args)
{
var person = new Person();
person.GetName();//error here
}
}
public interface IPerson
{
string GetName()
{
return "Jonny";
}
}
public class Person: IPerson
{
}
}
Run Code Online (Sandbox Code Playgroud)
我想我可以从这个人本身访问默认实现 oif GetName ,因为它是一个公共方法,但它会产生这个错误:
'Person' does not contain a definition for 'GetName' and no accessible extension method 'GetName' accepting a first argument of type 'Person' could be found (are you missing a using directive …
Run Code Online (Sandbox Code Playgroud) 这是我的AC#项目中的代码,该代码针对Visual Studio 2019(16.3.9)的.NET Core 3.0(因此我应该在C#8.0中)
public interface IJsonAble
{
public string ToJson() => System.Text.Json.JsonSerializer.Serialize(this);
}
public class SumRequest : IJsonAble
{
public int X { get; set; }
public int Y { get; set; }
public void Tmp()
{
new SumRequest().ToJson(); //compile error
}
}
Run Code Online (Sandbox Code Playgroud)
编译错误是:
CS1061'SumRequest'不包含'ToJson'的定义,并且找不到可以接受的扩展方法'ToJson'接受类型为'SumRequest'的第一个参数(您是否缺少using指令或程序集引用?)
有人可以阐明这种行为吗?
C# 8.0 有一项新功能,允许您向接口上的方法添加默认实现。要么我做错了什么,要么这个功能没有像宣传的那样工作。(我猜是前者。)
我使用以下代码创建了一个新的 .NET Core 3.1 控制台应用程序:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var xxx = new MyClass { MyInt = 5 };
Console.WriteLine(xxx.GetItNow());
}
}
public interface ITest
{
int MyInt { get; set; }
int GetItNow() => MyInt * 2;
}
public class MyClass : ITest
{
public int MyInt { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
该Console.WriteLine(xxx.GetItNow()));
语句无法编译,因为
Myclass 不包含“GetItNow()”的定义...
MyClass
因此,编译器对没有显式引用这一事实感到满意GetItNow()
(它不会抱怨MyClass
没有实现接口)。但它不会将默认接口成员视为实现该接口的类的公共方法。
我是否遗漏了什么,或者有什么东西坏了?
我在 .NET Core 3.1 和 C# 8 中有这个简单的控制台程序:
using System;
namespace ConsoleApp34
{
public interface ITest
{
public void test()
{
Console.WriteLine("Bye World!");
}
}
public class Test : ITest
{
public void CallDefault()
{
((ITest)(this)).test();
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var t = new Test();
t.CallDefault();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么演员阵容是必要的 ((ITest)(this)).test();
Test 直接派生自 ITest,因此,根据定义,'this' 是 ITest
谢谢你。
在 C#8 中,微软为接口方法引入了默认实现。这仍然是一个相当新的功能,似乎有很多关注的博主在写这个。
我想知道的是,默认实现是否有可能成为依赖倒置和 DI 的有用工具,或者它是否会促进不良的编程风格?它是否违反了任何众所周知的原则,如 SOLID?
c# dependency-injection solid-principles c#-8.0 default-interface-member
如果我有一个界面IExampleInterface
:
interface IExampleInterface {
int GetValue();
}
Run Code Online (Sandbox Code Playgroud)
GetValue()
有没有办法在子接口中提供默认实现?IE:
interface IExampleInterfaceChild : IExampleInterface {
// Compiler warns that we're just name hiding here.
// Attempting to use 'override' keyword results in compiler error.
int GetValue() => 123;
}
Run Code Online (Sandbox Code Playgroud) 我们有接口和实现类:
pubic interface IStackContainer {
const string DefaultStack = "default";
}
public class StackContainer<T> : MyBaseStackContainer<T>, IStackContainer{
protected internal string Stack {
get { return Get(nameof(Stack), IInterface.DefaultStack); } //works fine
set { Set(nameof(Stack), DefaultStack, value); } //doesn't exist in the current context, why?
}
}
Run Code Online (Sandbox Code Playgroud)
为什么我不能在没有“IInterface.”的情况下访问 StackContainer 中的常量?
PS:我的目的是将 const 放置在某个地方而不是 StackContainer 以便轻松访问它。如果它是在 StackContainer 中定义的,我可以像这样使用它:StackContainer.DefaultStack,但我认为这不是一个好的决定。
为什么接口成员的C#8默认实现会报告错误?
public interface Logger
{
void Info(string message);
void Error(string message);
// C#8 Default implementations of interface
void Warn(string message)
{
// "interface method cannot declare a body" error message
}
}
Run Code Online (Sandbox Code Playgroud)
和
.NET Core 3.0的配置如屏幕截图所示。