c# - 使用动态值调用抽象基类方法

标签 c#

我试图从一个带有动态变量的继承抽象基类中调用一个方法,但它因溢出异常而失败。

可以在以下位置测试可运行版本(带有 bool 值): https://dotnetfiddle.net/hSfsZl

可以在以下位置找到崩溃的可运行版本(具有动态值): https://dotnetfiddle.net/qXlMZD

public static void Main(string[] args)
{

    dynamic processed = true;
    // this works though
    //bool visible = true; 
    var data = new TemplateData<string>();
    var dataProcessor = new TemplateDataProcessor<string>(data);
    dataProcessor.Process(processed);

    Console.WriteLine(data.Processed);
}

public class Data : IData
{
    public bool Processed { get; set; }
}

public interface IData
{
    bool Processed { get; set; }
}

public abstract class DataProcessorBase<TData, TDataBuilder>
    where TDataBuilder : DataProcessorBase<TData, TDataBuilder>
    where TData : IData
{

    public TData Data { get; set; }

    public DataProcessorBase(TData data)
    {
        Data = data;
    }

    public TDataBuilder Process(bool value)
    {
        Data.Processed = value;

        return this as TDataBuilder;
    }
}


public abstract class DataProcessor<TData, TDataBuilder> : DataProcessorBase<TData, TDataBuilder>
    where TDataBuilder : DataProcessor<TData, TDataBuilder>
    where TData : IData
{
    public DataProcessor(TData data)
        : base(data)
    {

    }
}

public interface ITemplateData<T> : IData
    where T : class
{
    string Template { get; set; }
}

public class TemplateData<T> : ITemplateData<T>
    where T : class
{
    public string Template { get; set;  }

    public bool Processed { get; set; }
}

public class TemplateDataProcessor<T> : DataProcessor<ITemplateData<T>, TemplateDataProcessor<T>>
//public class TemplateDataProcessor<T> : DataProcessorBase<ITemplateData<T>, TemplateDataProcessor<T>>
    where T : class
{
    public TemplateDataProcessor(ITemplateData<T> data)
        : base(data)
    {
    }
}

使用 bool 值调用 dataProcessor.Process(processed); 按预期工作,但使用等于 true 的动态变量调用它会抛出异常。另外,从基础抽象类继承解决了这个问题

public class TemplateDataProcessor<T> : DataProcessorBase<ITemplateData<T>, TemplateDataProcessor<T>>

为什么这不起作用?此外,为什么从基类继承 - DataProcessorBase - 即使使用动态值也能正常工作?以下破坏代码的继承有什么问题:

public abstract class DataProcessor<TData, TDataBuilder> : DataProcessorBase<TData, TDataBuilder>

是否可以通过满足以下所有要求来解决此问题:

  1. 不要将任何方法从 DataProcessorBase 移动到 DataProcessor 类或更改它们的代码,例如不允许更改为 Process(dynamic value)
  2. 将使用动态调用 dataProcessor.Process,即不能强制 API 的最终用户使用 bool 而不是 dynamic。

最佳答案

这似乎是 .NET 本身的问题 - 在动态调度中,如调用堆栈所示:它只是重复

TypeManager.SubstTypeCore(type, pctx)
TypeManager.SubstTypeArray(taSrc, pctx)
TypeManager.SubstTypeCore(type, pctx)
AggregateType.GetBaseClass()
TypeManager.GetAggregate(agg, atsOuter, typeArgs)
TypeManager.GetAggregate(agg, typeArgsAll)
SymbolTable.GetConstructedType(type, agg)
SymbolTable.LoadSymbolsFromType(originalType)
TypeManager.GetAggregate(agg, atsOuter, typeArgs)
TypeManager.GetAggregate(agg, typeArgsAll)
TypeManager.SubstTypeCore(type, pctx)
TypeManager.SubstTypeArray(taSrc, pctx)
TypeManager.SubstTypeCore(type, pctx)
AggregateType.GetBaseClass()
TypeManager.GetAggregate(agg, atsOuter, typeArgs)
TypeManager.GetAggregate(agg, typeArgsAll)
SymbolTable.GetConstructedType(type, agg)
SymbolTable.LoadSymbolsFromType(originalType)
TypeManager.GetAggregate(agg, atsOuter, typeArgs)
TypeManager.GetAggregate(agg, typeArgsAll)
TypeManager.SubstTypeCore(type, pctx)
TypeManager.SubstTypeArray(taSrc, pctx)
TypeManager.SubstTypeCore(type, pctx)
AggregateType.GetBaseClass()
TypeManager.GetAggregate(agg, atsOuter, typeArgs)
TypeManager.GetAggregate(agg, typeArgsAll)
SymbolTable.GetConstructedType(type, agg)
SymbolTable.LoadSymbolsFromType(originalType)
TypeManager.GetAggregate(agg, atsOuter, typeArgs)
AggregateSymbol.getThisType()
SymbolTable.AddAggregateToSymbolTable(parent, type)
SymbolTable.LoadSymbolsFromType(originalType)
SymbolTable.GetConstructedType(type, agg)
SymbolTable.LoadSymbolsFromType(originalType)
SymbolTable.GetConstructedType(type, agg)
SymbolTable.LoadSymbolsFromType(originalType)
SymbolTable.CreateInheritanceHierarchyList(type)
SymbolTable.PopulateSymbolTableWithName(name, typeArguments, callingType)
PopulateSymbolTableWithPayloadInformation(payload, callingType, arguments)
BindCore(payload, parameters, args, deferredBinding)
Bind(payload, parameters, args, deferredBinding)
BinderHelper.Bind(action, binder, args, arginfos, onBindingError)
CSharpInvokeMemberBinder.FallbackInvokeMember(target, args, errorSuggestion)
DynamicMetaObject.BindInvokeMember(binder, args)
InvokeMemberBinder.Bind(target, args)
DynamicMetaObjectBinder.Bind(args, parameters, returnLabel)
CallSiteBinder.BindCore<System.Action<System.Runtime.CompilerServices.CallSite, Program.TemplateDataProcessor<string>, object>>(site, args)
UpdateDelegates.UpdateAndExecuteVoid2<Program.TemplateDataProcessor<string>, object>(site, arg0, arg1)
Program.Main(args)

我会向 Microsoft 报告

关于c# - 使用动态值调用抽象基类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56269959/

相关文章:

c# - UIImagePickerController 出现 "Attempt to present Xamarin_Forms_Platform_iOS_ModalWrapper whose view is not in the window hierarchy"错误

c# - 如何从 json 序列化中排除特定类型

C# 析构函数在超出范围后不调用

c# - 我可以将 Unity 场景公开为 Web 服务吗?

c# - 在 .NET 中从内存下载并运行 JAR

c# - 绑定(bind)到 XAML 中的 Xamarin Picker SelectedItem 而不是重新加载表单

c# - 将连接字符串与后端代码分离

C#:子类列表 <Something>?

c# - 使用 LINQ 将列表转换为列表的列表

c# - 在 WPF 中拖放图像