1

I have several places where i have Action<Int32>, Action<Boolean>, Action<SomeClassName> being used, but when it comes to passing the action as an argument in a class method, i cannot cast Action<Int32> or Action<Boolean> to Action<Object>.

Why can a cast not be done with a simple type cast? Is this cast possible at all? And lastly, how would i go about this cast if it is possible.


Combine the legends of shaded error and solid line mean

I am using this FEX entry to plot the horizontal shaded error bars for a variable plotted on the X-axis. This variable is plotted in different regions/zones and, therefore, there are 3 shaded error bars for 3 zones. I would like to combine the legends of the error bars (shaded region) as well as the mean (solid line) of any zone into a single legend represented by a solid line (or solid line inside a patch) of the same color as the zone.

THE WAY MY CODE WORKS FOR PLOTTING: A synthetic example of the way I am plotting is shown below

fh = figure();
axesh = axes('Parent', fh);
nZones = 4;
nPts = 10;
X = nan*ones(nPts, nZones);
Y = nan*ones(nPts, nZones);
XError = nan*ones(10, 4);
clr = {'r', 'b', 'g', 'm', 'y', 'c'};
for iZone = 1:nZones
    X(:, iZone) = randi(10, nPts, 1);
    Y(:, iZone) = randi(10, nPts, 1);
    XError(:, iZone) = rand(nPts, 1);
    % Append Legend Entries/Tags
    if iZone == 1
        TagAx = {['Zone # ', num2str(iZone)]};
    else
        TagAx = [TagAx, {['Zone # ', num2str(iZone)]}];
    end
    hold(axesh, 'on')
    [hLine, hPatch] = boundedline(X(:, iZone), Y(:, iZone), XError(:, iZone),...
        strcat('-', clr{iZone}), axesh, 'transparency', 0.15,...
        'orientation', 'horiz');
    legend(TagAx);
    xlabel(axesh, 'X', 'Fontweight', 'Bold');
    ylabel(axesh, 'Y', 'Fontweight', 'Bold');
    title(axesh, 'Error bars in X', 'Fontweight', 'Bold');
end

THE WAY LEGENDS ARE SHOWING-UP CURRENTLY:

enter image description here

WHAT I HAVE TRIED: As someone suggested in the comment section of that file's FEX page to add the following code after line 314 in boundedline code.

set(get(get(hp(iln),'Annotation'),'LegendInformation'),'IconDisplayStyle','off');

However, on doing that I get this error:

The name 'Annotation' is not an accessible property for an instance of class 'root'.

EDIT: The first two answers suggested accessing the legend handles of the patch and line which are returned as output the by the function boundedline. I tried that but the problem is still not solved as the legend entries are still not consistent with the zones.

4

3 回答 3

10

因为它会破坏类型安全。

当您声明时Action<Int32>,您会说“这是一个需要一个 Int32 参数的委托”。

如果这可以直接转换为Action<object>,那么您现在可以使用绝对不是的东西来调用动作Int32,例如 a DateTime。在这种情况下,C# 会阻止您朝自己的脚开枪。

于 2013-07-12T14:25:02.597 回答
3

您不能通过协变(或者是逆变?)进行直接转换,因为 anAction<int>基本上不是an Action<object>- 后者可以传递任何对象,而前者只能传递 an int

可以通过包装您的操作来解决此问题,例如:

Action<int> aInt = ...;
Action<object> aObj = o => aInt((int)o);

这再次向您展示了为什么强制转换可能不是一个好主意 - 如果您传递aObj除 a 之外的任何内容int,您将获得强制转换异常。

相反,理论上您可以Action<object>将 an 强制转换为 an Action<int>,因为如果您可以将任何对象传递给它,那么您当然可以将它传递给int。但是,在实践中,这只适用于引用类型,而不适用于值类型——所以你可以用 来做string,但不能用int

于 2013-07-12T14:25:38.327 回答
1

动作在其输入为 Int32 的限制下工作。这意味着您使用的操作可以假设输入是 int。例如,您可以使用另一个 int 进行数学运算n => Console.WriteLine(n + 4)。因此,该动作或功能非常适合该框。如果你改变这个盒子,之前所做的假设仍然必须成立。您基本上与“常规”铸造场景具有反向关系或逆变性,例如:object a = (object) 2;.

请记住,任何适合 Action 框的东西都不必对其输入的行为做出任何假设。该功能n => Console.WriteLine(n)紧贴内部,因为可以打印所有对象。并非所有对象都可以像整数一样工作。

于 2013-07-12T14:31:43.393 回答