Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.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# C语言中的泛型类#_C# - Fatal编程技术网

C# C语言中的泛型类#

C# C语言中的泛型类#,c#,C#,假设我有以下几点: public class DataType1 { public DataType1() { } public string Read() { return "dt1"; } } public class DataType2 { public DataType2() { } public string Read() { return "dt2"; } } 和一个实用程序类: public class Logger<T> {

假设我有以下几点:

public class DataType1
{
    public DataType1() { }

    public string Read() { return "dt1"; }
}

public class DataType2
{
    public DataType2() { }

    public string Read() { return "dt2"; }
}
和一个实用程序类:

public class Logger<T>
{
    public Logger() { }
}
公共类记录器
{
公共记录器(){}
}
然后,在我的主应用程序中:

class Program
{
    static void Main(string[] args)
    {
        var test1 = new Logger<DataType1>();
        test1.Read(); // I want this to equal "dt1";

        var test2 = new Logger<DataType2>();
        test2.Read(); // I want this to equal "dt2";
    }
 }
类程序
{
静态void Main(字符串[]参数)
{
var test1=新的记录器();
test1.Read();//我希望它等于“dt1”;
var test2=新的记录器();
test2.Read();//我希望它等于“dt2”;
}
}
我意识到我在尝试做一种协方差。但是,我不能让DataType1/DataType2从记录器继承-这将违反体系结构(即DataType1/DataType2位于DAL,程序员需要通过记录器到达DAL)

有没有想过我该如何做到这一点

谢谢。

使用界面:

public interface IDataType
{
    string Read();
}

public class DataType1 : IDataType
{
    public DataType1() { }

    public string Read() { return "dt1"; }
}

public class DataType2 : IDataType
{
    public DataType2() { }

    public string Read() { return "dt2"; }
}

public class Logger<T> where T : IDataType, new()
{
    IDataType dataType { get; set; }

    public Logger() {
        dataType = new T();
    }

    public string Read()
    {
        return dataType.Read();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var test1 = new Logger<DataType1>();
        test1.Read(); // I want this to equal "dt1";

        var test2 = new Logger<DataType2>();
        test2.Read(); // I want this to equal "dt2";
    }
}
public class Logger<T> where T : IReadable
public interface IReader
{
    public String Read();
}
使用接口:

public interface IDataType
{
    string Read();
}

public class DataType1 : IDataType
{
    public DataType1() { }

    public string Read() { return "dt1"; }
}

public class DataType2 : IDataType
{
    public DataType2() { }

    public string Read() { return "dt2"; }
}

public class Logger<T> where T : IDataType, new()
{
    IDataType dataType { get; set; }

    public Logger() {
        dataType = new T();
    }

    public string Read()
    {
        return dataType.Read();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var test1 = new Logger<DataType1>();
        test1.Read(); // I want this to equal "dt1";

        var test2 = new Logger<DataType2>();
        test2.Read(); // I want this to equal "dt2";
    }
}
public class Logger<T> where T : IReadable
public interface IReader
{
    public String Read();
}
使用接口:

public class DataType1 : IReadable
{
    public DataType1() { }

    public string Read() { return "dt1"; }
}

public class DataType2 : IReadable
{
    public DataType2() { }

    public string Read() { return "dt2"; }
}

public interface IReadable
{
    string Read();
}
并强制泛型类型实现此接口:

public interface IDataType
{
    string Read();
}

public class DataType1 : IDataType
{
    public DataType1() { }

    public string Read() { return "dt1"; }
}

public class DataType2 : IDataType
{
    public DataType2() { }

    public string Read() { return "dt2"; }
}

public class Logger<T> where T : IDataType, new()
{
    IDataType dataType { get; set; }

    public Logger() {
        dataType = new T();
    }

    public string Read()
    {
        return dataType.Read();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var test1 = new Logger<DataType1>();
        test1.Read(); // I want this to equal "dt1";

        var test2 = new Logger<DataType2>();
        test2.Read(); // I want this to equal "dt2";
    }
}
public class Logger<T> where T : IReadable
public interface IReader
{
    public String Read();
}
其用途是:

var dt1 = new DataType1();
var dt2 = new DataType2();
var logger1 = new Logger<DataType1>(dt1);
var logger2 = new Logger(dt2); // can omit generic noise!
Console.WriteLine(logger1.Read()); // "dt1"
Console.WriteLine(logger2.Read()); // "dt2"
var logger1 = new Logger<DataType1>();
Console.WriteLine(logger1.Read()); // "dt1"
其用途是:

var dt1 = new DataType1();
var dt2 = new DataType2();
var logger1 = new Logger<DataType1>(dt1);
var logger2 = new Logger(dt2); // can omit generic noise!
Console.WriteLine(logger1.Read()); // "dt1"
Console.WriteLine(logger2.Read()); // "dt2"
var logger1 = new Logger<DataType1>();
Console.WriteLine(logger1.Read()); // "dt1"
var logger1=new Logger();
Console.WriteLine(logger1.Read());//“dt1”
使用接口:

public class DataType1 : IReadable
{
    public DataType1() { }

    public string Read() { return "dt1"; }
}

public class DataType2 : IReadable
{
    public DataType2() { }

    public string Read() { return "dt2"; }
}

public interface IReadable
{
    string Read();
}
并强制泛型类型实现此接口:

public interface IDataType
{
    string Read();
}

public class DataType1 : IDataType
{
    public DataType1() { }

    public string Read() { return "dt1"; }
}

public class DataType2 : IDataType
{
    public DataType2() { }

    public string Read() { return "dt2"; }
}

public class Logger<T> where T : IDataType, new()
{
    IDataType dataType { get; set; }

    public Logger() {
        dataType = new T();
    }

    public string Read()
    {
        return dataType.Read();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var test1 = new Logger<DataType1>();
        test1.Read(); // I want this to equal "dt1";

        var test2 = new Logger<DataType2>();
        test2.Read(); // I want this to equal "dt2";
    }
}
public class Logger<T> where T : IReadable
public interface IReader
{
    public String Read();
}
其用途是:

var dt1 = new DataType1();
var dt2 = new DataType2();
var logger1 = new Logger<DataType1>(dt1);
var logger2 = new Logger(dt2); // can omit generic noise!
Console.WriteLine(logger1.Read()); // "dt1"
Console.WriteLine(logger2.Read()); // "dt2"
var logger1 = new Logger<DataType1>();
Console.WriteLine(logger1.Read()); // "dt1"
其用途是:

var dt1 = new DataType1();
var dt2 = new DataType2();
var logger1 = new Logger<DataType1>(dt1);
var logger2 = new Logger(dt2); // can omit generic noise!
Console.WriteLine(logger1.Read()); // "dt1"
Console.WriteLine(logger2.Read()); // "dt2"
var logger1 = new Logger<DataType1>();
Console.WriteLine(logger1.Read()); // "dt1"
var logger1=new Logger();
Console.WriteLine(logger1.Read());//“dt1”

正如@leppie所说的,如果您要在通用实用程序类声明上添加约束。它可以解决这个问题。您需要通过构造函数或使用属性来注入对记录器类的依赖关系

例如,假设您有以下接口:

public interface IDataType
{
    string Read();
}

public class DataType1 : IDataType
{
    public DataType1() { }

    public string Read() { return "dt1"; }
}

public class DataType2 : IDataType
{
    public DataType2() { }

    public string Read() { return "dt2"; }
}

public class Logger<T> where T : IDataType, new()
{
    IDataType dataType { get; set; }

    public Logger() {
        dataType = new T();
    }

    public string Read()
    {
        return dataType.Read();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var test1 = new Logger<DataType1>();
        test1.Read(); // I want this to equal "dt1";

        var test2 = new Logger<DataType2>();
        test2.Read(); // I want this to equal "dt2";
    }
}
public class Logger<T> where T : IReadable
public interface IReader
{
    public String Read();
}
我们会让DataType1和DataType2看起来像

 public class DataType1:IReader
{
    public String Read()
    {
        return "dt1";
    }
}
您的实用程序类可能会变成如下内容:

 public class Logger<T> where T:IReader
{
    private T dataTypeInstance;

    public Logger(T dataTypeInstance)
    {
        this.dataTypeInstance = dataTypeInstance;
    }

    public String Read()
    {
        return dataTypeInstance.Read();

    }
}
 var test1 = new Logger<DataType1>(dataType1);
 var test2 = new Logger<DataType2>(dataType2);

 test1.Read(); //will be dt1
 test2.Read(); //will be dt2
公共类记录器,其中T:IReader
{
私有T数据类型实例;
公共记录器(T数据类型实例)
{
this.dataTypeInstance=dataTypeInstance;
}
公共字符串读取()
{
返回dataTypeInstance.Read();
}
}
它的Read方法将简单地调用数据类型类的Read方法

然后,我们可以从某种工厂获得DataType1和DataType2的实例 然后用以下方法进行测试:

 public class Logger<T> where T:IReader
{
    private T dataTypeInstance;

    public Logger(T dataTypeInstance)
    {
        this.dataTypeInstance = dataTypeInstance;
    }

    public String Read()
    {
        return dataTypeInstance.Read();

    }
}
 var test1 = new Logger<DataType1>(dataType1);
 var test2 = new Logger<DataType2>(dataType2);

 test1.Read(); //will be dt1
 test2.Read(); //will be dt2
var test1=新记录器(数据类型1);
var test2=新的记录器(数据类型2);
test1.Read()//将是dt1
test2.Read()//将是dt2

或者,您可以使用反射和属性文件或(数据库存储的配置),而不是通过构造函数或实用程序类中的属性使用依赖项注入与
一起使用的是
运算符,用于获取要使用的正确数据类型的实例。

正如@leppie所说的,如果要在通用实用程序类声明上添加约束。它可以解决这个问题。您需要通过构造函数或使用属性来注入对记录器类的依赖关系

例如,假设您有以下接口:

public interface IDataType
{
    string Read();
}

public class DataType1 : IDataType
{
    public DataType1() { }

    public string Read() { return "dt1"; }
}

public class DataType2 : IDataType
{
    public DataType2() { }

    public string Read() { return "dt2"; }
}

public class Logger<T> where T : IDataType, new()
{
    IDataType dataType { get; set; }

    public Logger() {
        dataType = new T();
    }

    public string Read()
    {
        return dataType.Read();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var test1 = new Logger<DataType1>();
        test1.Read(); // I want this to equal "dt1";

        var test2 = new Logger<DataType2>();
        test2.Read(); // I want this to equal "dt2";
    }
}
public class Logger<T> where T : IReadable
public interface IReader
{
    public String Read();
}
我们会让DataType1和DataType2看起来像

 public class DataType1:IReader
{
    public String Read()
    {
        return "dt1";
    }
}
您的实用程序类可能会变成如下内容:

 public class Logger<T> where T:IReader
{
    private T dataTypeInstance;

    public Logger(T dataTypeInstance)
    {
        this.dataTypeInstance = dataTypeInstance;
    }

    public String Read()
    {
        return dataTypeInstance.Read();

    }
}
 var test1 = new Logger<DataType1>(dataType1);
 var test2 = new Logger<DataType2>(dataType2);

 test1.Read(); //will be dt1
 test2.Read(); //will be dt2
公共类记录器,其中T:IReader
{
私有T数据类型实例;
公共记录器(T数据类型实例)
{
this.dataTypeInstance=dataTypeInstance;
}
公共字符串读取()
{
返回dataTypeInstance.Read();
}
}
它的Read方法将简单地调用数据类型类的Read方法

然后,我们可以从某种工厂获得DataType1和DataType2的实例 然后用以下方法进行测试:

 public class Logger<T> where T:IReader
{
    private T dataTypeInstance;

    public Logger(T dataTypeInstance)
    {
        this.dataTypeInstance = dataTypeInstance;
    }

    public String Read()
    {
        return dataTypeInstance.Read();

    }
}
 var test1 = new Logger<DataType1>(dataType1);
 var test2 = new Logger<DataType2>(dataType2);

 test1.Read(); //will be dt1
 test2.Read(); //will be dt2
var test1=新记录器(数据类型1);
var test2=新的记录器(数据类型2);
test1.Read()//将是dt1
test2.Read()//将是dt2

或者,您可以使用反射和属性文件或(数据库存储的配置)以及
is
操作符来获取要使用的正确数据类型的实例,而不是通过构造函数或实用程序类中的属性使用依赖项注入。

如果无法使用接口,请尝试使用lambda exprestion:

public class Logger<T>  where T : new()
{
    private Func<T, string> _readFunc;
    private T _member;

    public Logger(Func<T, string> readFunc) 
    {
        _readFunc = readFunc; 
        _member  = new T();
    }

    // Use this if you already have an instance of your data type
    public Logger(Func<T, string> readFunc, T member)
    {
       _readFunc = readFunc;
       _member  = member;
    }

    public string Read()
    {
        return _readFunc(_member); 
    }
}
公共类记录器,其中T:new()
{
私有函数_readFunc;
私人旅游联盟成员;
公共记录器(Func readFunc)
{
_readFunc=readFunc;
_成员=新的T();
}
//如果已经有数据类型的实例,请使用此选项
公共记录器(Func readFunc,T成员)
{
_readFunc=readFunc;
_成员=成员;
}
公共字符串读取()
{
返回_readFunc(_成员);
}
}
然后在你的应用程序中:

static void Main()
{
    var test1 = new Logger<DataType1>(t => t.Read());
    test1.Read(); // Will be equal "dt1";

    var test2 = new Logger<DataType2>(t => t.Read());
    test2.Read(); // Will be equal "dt2";
}
static void Main()
{
var test1=newlogger(t=>t.Read());
test1.Read();//将等于“dt1”;
var test2=newlogger(t=>t.Read());
test2.Read();//将等于“dt2”;
}

如果无法使用接口,请尝试使用lambda exprestion:

public class Logger<T>  where T : new()
{
    private Func<T, string> _readFunc;
    private T _member;

    public Logger(Func<T, string> readFunc) 
    {
        _readFunc = readFunc; 
        _member  = new T();
    }

    // Use this if you already have an instance of your data type
    public Logger(Func<T, string> readFunc, T member)
    {
       _readFunc = readFunc;
       _member  = member;
    }

    public string Read()
    {
        return _readFunc(_member); 
    }
}
公共类记录器,其中T:new()
{
私有函数_readFunc;
私人旅游联盟成员;
公共记录器(Func readFunc)
{
_readFunc=readFunc;
_成员=新的T();
}
//如果已经有数据类型的实例,请使用此选项
公共记录器(Func readFunc,T成员)
{
_readFunc=readFunc;
_成员=成员;
}
公共字符串读取()
{
返回_readFunc(_成员);
}
}
然后在你的应用程序中:

static void Main()
{
    var test1 = new Logger<DataType1>(t => t.Read());
    test1.Read(); // Will be equal "dt1";

    var test2 = new Logger<DataType2>(t => t.Read());
    test2.Read(); // Will be equal "dt2";
}
static void Main()
{
var test1=newlogger(t=>t.Read());
test1.Read();//将等于“dt1”;
var test2=newlogger(t=>t.Read());
test2.Read();//将等于“dt2”;
}

类记录器where T:someInterfaceWithThreadMethod
类记录器where T:SomeInterfaceWithReadMethod谢谢,在一些深夜和截止日期之后,我觉得更容易问‘因为我的大脑刚刚死去……)谢谢,在一些深夜和最后期限之后,我觉得更容易问‘因为我的大脑已经死了……:)