为什么这在C#中是不可能的?

为什么这在C#中是不可能的?,c#,.net,generics,C#,.net,Generics,当我写下面的代码时: public interface IDoSomething<in TFrom> { void Process(TFrom content, string path); void Process<TTemplate>(TFrom content, TTemplate template, string path); } public class ConcreteWorkA<str

当我写下面的代码时:

public interface IDoSomething<in TFrom> 
    {
        void Process(TFrom content, string path);

        void Process<TTemplate>(TFrom content, TTemplate template, string path);

    }

       public class ConcreteWorkA<string> : IDoSomething<string>
    {

        public void Process(string content, string path)
        {
            throw new NotImplementedException();
        }

        public void Process<TTemplate>(string content, TTemplate template, string path)
        {
            throw new NotImplementedException();
        }

    }

   
公共接口
{
作废处理(从内容、字符串路径中读取);
作废流程(内容、模板模板、字符串路径);
}
A:我有什么事
{
公共作废进程(字符串内容、字符串路径)
{
抛出新的NotImplementedException();
}
公共作废流程(字符串内容、TTemplate模板、字符串路径)
{
抛出新的NotImplementedException();
}
}
它不会在下行编译的地方编译

     public class ConcreteWorkB<String> : IDoSomething<String>
    {

        public void Process(String content, string path)
        {
            throw new NotImplementedException();
        }

        public void Process<TTemplate>(String content, TTemplate template, string path)
        {
            throw new NotImplementedException();
        }

    }
公共类混凝土工程b:idoothing
{
公共作废进程(字符串内容、字符串路径)
{
抛出新的NotImplementedException();
}
公共作废流程(字符串内容、TTemplate模板、字符串路径)
{
抛出新的NotImplementedException();
}
}
我也知道,
public class-ConcreteWorkB:I有些东西是正确的,但下面的代码是有效的

     public class COncreteWorkC<DataTable> : IDoSomething<DataTable>// Datatable from System.Data
    {
        public void Process(DataTable content, string path)
        {
            throw new NotImplementedException();
        }

        public void Process<TTemplate>(DataTable content, TTemplate template, string path)
        {
            throw new NotImplementedException();
        }                 
    }
公共类COncreteWorkC:IDOSthing//System.Data中的Datatable
{
公共作废进程(数据表内容、字符串路径)
{
抛出新的NotImplementedException();
}
公共作废流程(数据表内容、TTemplate模板、字符串路径)
{
抛出新的NotImplementedException();
}                 
}
因为string是string的别名,所以我希望它能工作。这也是为什么行为上的差异。 我使用的是VS2019,.NET5

我得到的错误是

  • 应为语法错误“,”
  • 应为标识符

  • 编辑:注释和接受的答案解释字符串/数据表被视为泛型类型参数,而不是具体类型,其中as String就是错误所在。

    这是您的实际代码吗?如果是这样的话,那么您需要一个我期望的类,可能还值得在该类的类型中添加'in'关键字:

    public interface IDoSomething<in TSource> : IDisposable{}
    public class DoesSomething<in string> : IDoSomething<string>
    {
        public void Dispose()
        {
        }
    }
    
    公共接口IDoSomething:IDisposable{}
    公共类做方法:我做某事
    {
    公共空间处置()
    {
    }
    }
    
    似乎是一个有趣的案例,说明什么是允许的泛型参数类型名称。 这:

    没有多大意义,因为它试图引入一个具体类型(
    string
    )作为参数名,其中只允许使用新名称

    这里唯一有趣的是,它实际上在泛型参数类型名与现有类型名发生冲突时起作用。看起来编译器允许这样做,但当然这两个
    String
    s的含义不同

    public interface IDoSomething<in TSource> : IDisposable { }
    
    class DoesSomething<String> : IDoSomething<String>
    {
        public void Dispose()
        {
        }
    }
    
    public class Program
    {
        public static void Main()
        {
            DoesSomething<int> _ = new DoesSomething<int>();
        }
    }
    
    公共接口IDoSomething:IDisposable{}
    课堂教学方法:我做了一些事情
    {
    公共空间处置()
    {
    }
    }
    公共课程
    {
    公共静态void Main()
    {
    DoesMething=新的DoesMething();
    }
    }
    
    IDoSomething
    中的
    字符串
    绑定到接口定义中的
    TSource


    doesmething
    中的
    String
    引入了一个类型参数,然后该参数将由客户端提供(
    int
    ,在上面的示例中)。

    您希望一行
    doesmething:IDoSomething{}
    做什么?请注意,
    doesmething:IDoSomething{}
    也不会编译。如果您试图指定一个类声明,请说明这一点。A将非常非常有助于您的问题。@JonSkeet:
    doesmething
    实际编译,似乎编译器将
    String
    视为泛型参数类型名称。如果这是
    类doesmething:IDoSomething{}
    ,那么第一个
    字符串是泛型类型的占位符名称,因此不允许使用它,因为它会将它与。我无法100%确定您是否认为指定的类型应为
    string
    ,或者您是否知道这是泛型类型参数的名称。请参阅。你误解了
    class-ConcreteWorkA:idomsomething
    class-COncreteWorkC
    所声明的内容。@anshu:提供一个最小的完整示例远远不是信息过载。不需要花太多时间就可以清楚地表明您正在尝试编写一个类声明。您的编辑仍然不完整,因为现在您还没有在任何地方声明
    IDoSomething
    。请阅读我认为区别在于
    string
    在C#语言中是一个类(尽管它只是一个别名),而
    string
    是由.NET提供的一个类。感谢您的详细解释,这是因为字符串被视为泛型类型参数而不是具体类型。虽然代码中的类型参数没有意义,但需要理解。@Llama:实际上
    string
    是一个类型别名
    System.String
    是内置的.NET类型。只要
    String
    就可以引用
    System.String
    ,假设您已经使用上面的
    系统或一个类型名,比如
    T
    。这就是为什么这个案子看起来很有趣的原因。@Wiktor我想你可能没有领会我的意思。是的,它是一个别名(如我所说),但该别名类型是C#语言固有的(是的语言,不是.NET-我知道这里的行有点模糊)
    String
    是别名类型,但它属于.NET,并且具有名称空间。关键是,您可以使用
    声明删除所有
    ,但仍然使用
    字符串
    ,因为它是语言的一部分,但您需要使用
    系统
    才能使用
    字符串
    (或者您可以将其引用为
    系统.string
    )因为它不是语言的一部分。即使在命名空间之外声明一个类,也不会阻止它的名称作为泛型类型使用,因此它必须是C语言的内置类型。
    class DoesSomething<T> : IDoSomething<String>
    {
        public void Dispose()
        {
        }
    }
    
    class DoesSomething<string> : IDoSomething<string>
    {
        public void Dispose()
        {
        }
    }
    
    public interface IDoSomething<in TSource> : IDisposable { }
    
    class DoesSomething<String> : IDoSomething<String>
    {
        public void Dispose()
        {
        }
    }
    
    public class Program
    {
        public static void Main()
        {
            DoesSomething<int> _ = new DoesSomething<int>();
        }
    }