在上面的代码段我有一个基类形状,并从它两个派生的类Rectangle和Triangle。我实例化了它们,但是对于一个Triangle对象,我使用其基类的引用类型。
因此,现在当我调用一个方法时calculate(),它将更喜欢调用采用基类参数的方法。
这样做的目的是什么?
我创建的Triangle对象不是Shape对象,我只是使用基类的引用。我的另一个问题是,与使用基类的引用和从派生实例化对象而不是使用派生引用相比,它们还有其他区别吗?
public static void Main(string[] args)
{
Point tc = new Point(3, 4);
Point rc = new Point(7, 5);
Shape shape = new Triangle(tc, 4, 4, 4);
calculate(shape);
}
public static void calculate(Shape shape) <<-- new Triangle() with base class ref will came here.
{
Console.WriteLine("shape");
}
public static void calculate(Rectangle rectangle)
{
Console.WriteLine("rectangle");
}
public static void calculate(Triangle triangle) <<-- new Triangle() using triangle …Run Code Online (Sandbox Code Playgroud) 好的,回到基础.我想知道如何使用params参数正确地重载方法.
这是我的情景.我从我的常规方法开始:
public void MyMethod(MyObject mo)
{
// method body
}
Run Code Online (Sandbox Code Playgroud)
我为它创建了一个重载,如下所示:
public void MyMethod(MyObject mo, params string[] fields)
{
// new method body
MyMethod(mo);
}
Run Code Online (Sandbox Code Playgroud)
显而易见的目的是MyMethod(new MyObject());执行原始方法并MyMethod(new MyObject(), "field0"/*, etc...*/);执行重载方法.但这不是我发现的情况.
实际发生的是MyMethod(new MyObject());执行重载方法!
我不明白.在这种情况下,我将如何执行原始方法?
好的,所以这里是产生所描述行为的实际代码.
Class1Base.cs:
public class Class1Base
{
public virtual void MyMethod(MyObject ob)
{
Console.WriteLine("Called Class1Base");
}
}
Run Code Online (Sandbox Code Playgroud)
将Class1.cs:
public class Class1 : Class1Base
{
public override void MyMethod(MyObject ob)
{
Console.WriteLine("called overridden method");
}
public void MyMethod(MyObject ob, …Run Code Online (Sandbox Code Playgroud) 我有两种重载方法,一种是期望对象类型参数,另一种是通用参数列表。我试图了解何时调用哪个函数。我正在传递字符串对象,它正在调用通用params方法。
class Program
{
static void Main(string[] args)
{
string s = "string";
Invoke(s);
Console.ReadLine();
}
static void Invoke(object s)
{
Console.WriteLine("Object param invoked");
}
static void Invoke<T>(params T[] values)
{
Console.WriteLine("Params method invoked");
}
}
Run Code Online (Sandbox Code Playgroud)
它的输出为:“ Params方法已调用”。
但我不确定为什么总是调用此方法。我也尝试传递int参数,但再次调用了params方法。如果有人可以帮我解释一下。谢谢。
我们最近在代码库中发现了一个问题,其中VS2019编译的代码很好,但VS 2017失败。
我为Union创建了一个扩展方法,该方法具有一个通用ISet作为通用约束
using System;
using System.Collections.Generic;
using System.Linq;
public static class Extensions
{
public static S Union<S, T>(this S self, IEnumerable<T> other) where S : ISet<T>, new()
{
//For simplicity issues since this is a compilation based question
return default(S);
}
public static void Test()
{
var values = new[] { 1, 2, 3 };
var values1 = new[] { 1, 2, 3, 4 };
values.Union(values1);
}
}
Run Code Online (Sandbox Code Playgroud)
Union生成编译错误,指出int []无法转换为ISet。
据我了解,方法解析最初忽略了通用约束。但似乎这段代码会在2019年编译。
我没有在发行说明中看到任何地方,它们指出他们已经解决了该错误或添加了新功能来改善通用方法的方法分辨率。
我正在寻找有关此问题的更多信息,这是Microsoft的错误修复程序还是预期的功能?
我发现C#的这个功能"命名参数"真的很奇怪,因为我看到了它的两个缺陷.该书说"命名参数赋予你"以任何顺序传递参数的能力".
我认为这个C#功能存在两个缺陷:
它违反了计算机科学中的"信息隐藏".(即:使用该方法的最终用户需要知道参数名称和数据类型才能使用该功能.)来自Java背景,这很奇怪.为什么要将参数名称暴露给用户的末尾?
它容易产生歧义,可能导致错误.(当程序员编写使用相同方法名称(也称为重载方法)的方法时,程序员需要进行额外的思考和问题.当你有两个同名的方法时,你总会得到一个"调用是不明确的"即使另一个方法具有不同数据类型的额外参数,彼此具有相同的参数.我能想到的唯一修复是使数据类型成为"强制参数",也就是没有默认值的参数,因此编译器会不要混淆.但是这个修复只是一个导致另一个最坏情况的绷带解决方案(见下文)
业内人士甚至在今天都使用这个概念吗?如果是这样,为什么要打破这两条规则"在调用方法时以任何顺序传递参数的能力"?
TLDR:通过引入可能的最坏情况场景(编译器选择了错误的方法调用......尽管两种方法相似)来清楚地说明我所说的内容:
namespace ConsoleApplication1
{
class Venusaur
{
static void Main(string[] args)
{
new Venusaur().optMethod(fourth: "s");
}
public void optMethod( string third , string fourth = "hello", int fifth = 23, string two = "w")
{
// what if I wanted this method to run instead of the method below me
Console.WriteLine("did not execute");
}
public void optMethod(string third = "Byte", string fourth = "hello", int fifth = 4)
{
// But this method ran instead …Run Code Online (Sandbox Code Playgroud) using System;
using System.Collections.Generic;
namespace Generics
{
class Minivan
{
public void foo(int z, int x)
{
Console.WriteLine("foo with two parameters");
}
public void foo(params int[] z)
{
Console.WriteLine("foo with two params parameter");
}
}
class D
{
public static void Main()
{
Minivan car3 = new Minivan();
car3.foo(10,20); // which method will be called here!!!
}
}
}
Run Code Online (Sandbox Code Playgroud)
哪个foo方法被调用?为什么?
c# ×6
.net ×2
overloading ×2
arguments ×1
methods ×1
parameters ×1
params ×1
polymorphism ×1
roslyn ×1