Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与泛型参数的接口vs与泛型方法的接口_C#_.net_Clr - Fatal编程技术网

C# 与泛型参数的接口vs与泛型方法的接口

C# 与泛型参数的接口vs与泛型方法的接口,c#,.net,clr,C#,.net,Clr,假设我有这样的接口和具体的实现 public interface IMyInterface<T> { T My(); } public class MyConcrete : IMyInterface<string> { public string My() { return string.Empty; } } 因此,我有相同的IMyInterface2,但它通过tmy()定义了泛型行为。在我的具体类中,我想实现我的行为,

假设我有这样的接口和具体的实现

public interface IMyInterface<T>
{
    T My();
}

public class MyConcrete : IMyInterface<string>
{
    public string My()
    {
        return string.Empty;
    }
}
因此,我有相同的
IMyInterface2
,但它通过
tmy()
定义了泛型行为。在我的具体类中,我想实现
我的
行为,但对于具体的数据类型-
字符串
。但C#不允许我这么做

我的问题是为什么我不能这样做?
换句话说,如果我可以将
MyInterface
创建为
MyClass:MyInterface
的具体实现,并在此时停止泛型性,那么为什么我不能用泛型方法-
t My()

您的泛型方法实现也必须是泛型的,所以它必须是:

public class MyConcrete2 : IMyInterface2
{
    public T My<T>()
    {
        throw new NotImplementedException();
    }
}
用法:

var item1=newmyclass21();
var item2=新的MyClass22();
//它们都实现了IMyInterface2,所以我们可以将它们放入列表中
var list=新列表();
增加(第1项);
增加(第2项);
//迭代列表并调用我的方法
foreach(列表中的IMyInterface2项)
{
//项是IMyInterface2,因此我们有My()方法。选择T为int并使用值2调用:
项目.My(2);
//它将如何处理item1,它已经实现了我的功能?
}

因为您的接口声明了一个泛型方法
T My()
,但您的实现没有实现具有该特定签名的函数

要实现您想要的功能,您需要为接口提供T generic参数,在第一个示例中:

public interface IMyInterface2<T>
{
        T My();
}

public class MyConcrete2 : IMyInterface2<string>
{
    public string My()
    {
        throw new NotImplementedException();
    }
}
公共接口IMyInterface2
{
T我的();
}
公共类MyConcrete2:IMyInterface2
{
公共字符串My()
{
抛出新的NotImplementedException();
}
}

编写通用方法时,定义用于保留占位符。当您调用该方法时,实际类型就会出现在图中。所以你应该写

public T My<T>()
{
    throw new NotImplementedException();
}
public T My()
{
抛出新的NotImplementedException();
}

当您调用该方法时,您可以使用那里的字符串。

您的解决方案不起作用有两个原因

首先,接口是一个契约。当您实现
IMyInterface2
时,您保证将实现名为
My
的函数,该函数接受泛型类型参数并返回该类型<代码>MyConcrete2不执行此操作


其次,C#泛型不允许任何类型参数专门化。(我希望C支持这个)。这是C++示例中常见的一个例子,在这里,您的示例将编译,但是如果代码不使用<代码>字符串调用<代码>我的<代码>,则任何代码的编译都不能编译。如果我可以将MyInterface的具体实现创建为MyClass:MyInterface,并在这一点上停止泛型,为什么我不能使用泛型方法-t My()?@JevgenijNekrasov检查我的更新。我显示了一种情况,您的
我的
实现将失败。同意。但事实上,在这种情况下,它可以使用实际类型,并使用对象的多态行为调用具体实现。您想怎么做?我想停止泛型,就像我可以使用泛型接口一样,例如MyClass:MyInterfaceI知道如何实现我想要的,我想知道为什么我不能停止泛化,因为我可以使用接口。在继承类型时,你不能减少能力,你只能增加它们。
var item1 = new MyClass21();
var item2 = new MyClass22();

// they both implement IMyInterface2, so we can put them into list
var list = new List<IMyInterface2>();
list.Add(item1);
list.Add(item2);

// iterate the list and call My method
foreach(IMyInterface2 item in list)
{
    // item is IMyInterface2, so we have My<T>() method. Choose T to be int and call with value 2:
    item.My<int>(2);

    // how would it work with item1, which has My<string> implemented?
}
public interface IMyInterface2<T>
{
        T My();
}

public class MyConcrete2 : IMyInterface2<string>
{
    public string My()
    {
        throw new NotImplementedException();
    }
}
public T My<T>()
{
    throw new NotImplementedException();
}