C# 保留一本字典<;类型,MyClass<;T>&燃气轮机;其中元素可按类型引用
我有一个名为EntityTypeTransform的抽象类,其中有一个抽象方法,用于保存将IDataRecord转换为T实例的Func委托C# 保留一本字典<;类型,MyClass<;T>&燃气轮机;其中元素可按类型引用,c#,generics,dictionary,C#,Generics,Dictionary,我有一个名为EntityTypeTransform的抽象类,其中有一个抽象方法,用于保存将IDataRecord转换为T实例的Func委托 public abstract class EntityTypeTransform<TEntityType> where TEntityType : class { public abstract Func<IDataRecord, TEntityType> GetDataTransform(); } 公共抽象类Entity
public abstract class EntityTypeTransform<TEntityType> where TEntityType : class
{
public abstract Func<IDataRecord, TEntityType> GetDataTransform();
}
公共抽象类EntityTypeTransform,其中TEntityType:class
{
公共抽象函数GetDataTransform();
}
该类的实现可能如下所示:
公共类任务ParameterEntityTypeTransform:EntityTypeTransform
{
公共覆盖函数GetDataTransform()
{
return dataRecord=>new TaskParameter()
{
TaskId=(int)数据记录[“任务id”],
名称=(字符串)数据记录[“p_名称”],
值=(字符串)数据记录[“p_值”]
};
}
}
现在我想在一个通用字典中保留这些类的一个实例,比如:
Dictionary<Type, EntityTypeTransform<T>>
字典
但这不起作用,因为(例如)Task的EntityTypeTransform实例与TaskParameter的EntityTypeTransform实例不同
有人能帮我吗
编辑:我应该添加Type key=typeof(T)您必须创建一个非泛型基类,例如
public abstract class EntityTypeTransformBase
{
public abstract Func<IDataRecord, object> GetDataTransform();
}
public abstract class EntityTypeTransform<TEntityType> : EntityTypeTransformBase where TEntityType : class
{
public abstract Func<IDataRecord, TEntityType> GetDataTransformImpl();
public override Func<IDataRecord, object> GetDataTransform()
{
return GetDataTransformImpl();
}
}
public class TaskParameterEntityTypeTransform : EntityTypeTransform<TaskParameter>
{
public override Func<IDataRecord, TaskParameter> GetDataTransformImpl()
{
return dataRecord => new TaskParameter()
{
TaskId = (int)dataRecord["task_id"],
Name = (string)dataRecord["p_name"],
Value = (string)dataRecord["p_value"]
};
}
}
公共抽象类EntityTypeTransformBase
{
公共抽象函数GetDataTransform();
}
公共抽象类EntityTypeTransform:EntityTypeTransformBase,其中TEntityType:class
{
公共抽象函数GetDataTransformImpl();
公共覆盖函数GetDataTransform()
{
返回GetDataTransformImpl();
}
}
公共类任务ParameterEntityTypeTransform:EntityTypeTransform
{
公共覆盖函数GetDataTransformImpl()
{
return dataRecord=>new TaskParameter()
{
TaskId=(int)数据记录[“任务id”],
名称=(字符串)数据记录[“p_名称”],
值=(字符串)数据记录[“p_值”]
};
}
}
现在,您可以创建字典:
var d = new Dictionary<Type, EntityTypeTransformBase>();
d.Add(typeof(TaskParameter), new TaskParameterEntityTypeTransform());
public interface IEntityTypeTransform<out TEntityType> where TEntityType : class
{
TEntityType Transform(IDataRecord dataRecord);
}
public abstract class EntityTypeTransform<TEntityType> : IEntityTypeTransform<TEntityType> where TEntityType : class
{
public abstract TEntityType Transform(IDataRecord dataRecord);
}
public class TaskParameter
{
public int TaskId;
public string Name;
public string Value;
}
public class TaskParameterEntityTypeTransform : EntityTypeTransform<TaskParameter>
{
public override TaskParameter Transform(IDataRecord dataRecord)
{
return new TaskParameter()
{
TaskId = (int)dataRecord["task_id"],
Name = (string)dataRecord["p_name"],
Value = (string)dataRecord["p_value"]
};
}
}
public class SomeClass
{
public KeyedByTypeCollection<IEntityTypeTransform<object>> TransformDictionary = new KeyedByTypeCollection<IEntityTypeTransform<object>>()
{
new TaskParameterEntityTypeTransform(),
// More transforms here
};
}
var d=newdictionary();
d、 添加(typeof(TaskParameter),新建TaskParameterEntityTypeTransform());
您可以使用非泛型接口,然后在该抽象类中显式实现该接口,这在.Net库中非常常见:
public interface IEntityTypeTransform
{
Func<IDataRecord, object> GetDataTransform();
}
public abstract class EntityTypeTransform<TEntityType> : IEntityTypeTransform
where TEntityType : class
{
public virtual Func<IDataRecord, TEntityType> GetDataTransform()
{
return this.GetDataTransformImpl();
}
public abstract Func<IDataRecord, TEntityType> GetDataTransformImpl();
Func<IDataRecord, object> IEntityTypeTransform.GetDataTransform()
{
return this.GetDataTransform();
}
}
公共接口IEntityTypeTransform
{
Func GetDataTransform();
}
公共抽象类EntityTypeTransform:EntityTypeTransform
其中TEntityType:类
{
公共虚拟函数GetDataTransform()
{
返回这个.GetDataTransformImpl();
}
公共抽象函数GetDataTransformImpl();
Func IEntityTypeTransform.GetDataTransform()
{
返回这个.GetDataTransform();
}
}
不能指定包含不同泛型类型的强类型集合。以下是我在类似问题中使用的方法,经过修改以符合您的要求:
class TransformCollection
{
private Hashtable cache = new Hashtable();
public void Add<T>(EntityTypeTransform<T> transform) where T : class
{
this.cache[typeof(T)] = itemToCache;
}
public bool Exists<T>() where T : class
{
return this.cache.ContainsKey(typeof(T));
}
public EntityTypeTransform<T> Get<T>() where T : class
{
if (!this.Exists<T>())
throw new ArgumentException("No cached transform of type: " + typeof(T).Name);
return this.cache[typeof(T)] as EntityTypeTransform<T>;
}
}
类集合
{
私有哈希表缓存=新哈希表();
公共void添加(EntityTypeTransform转换),其中T:class
{
this.cache[typeof(T)]=itemToCache;
}
public bool Exists(),其中T:class
{
返回this.cache.ContainsKey(typeof(T));
}
public EntityTypeTransform Get(),其中T:class
{
如果(!this.Exists())
抛出新的ArgumentException(“没有缓存的类型转换:”+typeof(T).Name);
将此.cache[typeof(T)]作为EntityTypeTransform返回;
}
}
这为泛型类型提供了类型安全缓存(尽管类型安全是由类的逻辑而不是C#强制实现的)。您可以按如下方式使用它:
var collection = new TransformCollection();
collection.Add(SomeMethodToGetTransform<Task>());
//...
if (collection.Exists<Task>())
{
var transform = collection.Get<Task>();
//...
}
var collection=new TransformCollection();
Add(SomeMethodToGetTransform());
//...
if(collection.Exists())
{
var transform=collection.Get();
//...
}
为变压器添加非通用接口:
public interface IEntityTypeTransform
{
Func<IDataRecord, object> GetDataTransform();
}
public abstract class EntityTypeTransform<T> : IEntityTypeTransform
{
public abstract Func<IDataRecord, object> GetDataTransform();
}
public class TaskParameterEntityTypeTransform : EntityTypeTransform<TaskParameter>
{
public override Func<IDataRecord, object> GetDataTransform()
{
return dataRecord => new TaskParameter()
{
TaskId = (int)dataRecord["task id"],
};
}
}
公共接口IEntityTypeTransform
{
Func GetDataTransform();
}
公共抽象类EntityTypeTransform:EntityTypeTransform
{
公共抽象函数GetDataTransform();
}
公共类任务ParameterEntityTypeTransform:EntityTypeTransform
{
公共覆盖函数GetDataTransform()
{
return dataRecord=>new TaskParameter()
{
TaskId=(int)数据记录[“任务id”],
};
}
}
然后可以封装字典,以确保数据类型始终匹配。决不允许添加错误类型的IEntityTypeTransform:
public class TransformDistributor
{
private readonly Dictionary<Type, IEntityTypeTransform> _transforms = new Dictionary<Type, IEntityTypeTransform>();
public void Add<T>(EntityTypeTransform<T> type)
{
this._transforms.Add(typeof(T), type);
}
public T Transform<T>(IDataRecord record)
{
var transform = this._transforms[typeof(T)].GetDataTransform()(record);
if (transform is T)
{
return (T)transform;
}
else
{
// theorically can't happen
throw new InvalidOperationException("transformer doesn't return instance of type " + transform.GetType().Name);
}
}
}
公共类分发服务器
{
私有只读字典_transforms=新字典();
公共void添加(EntityTypeTransform类型)
{
此._转换.Add(typeof(T),type);
}
公共T变换(IDataRecord记录)
{
var transform=此。_转换[typeof(T)]。GetDataTransform()(记录);
if(变换为T)
{
返回(T)变换;
}
其他的
{
//理论上不可能发生
抛出新的InvalidOperationException(“transformer不返回类型为“+transform.GetType().Name”的实例);
}
}
}
优点是,在编译时,您可以确保没有人可以插入坏的转换器,即使您没有使用泛型
用法:
var transforms = new TransformDistributor();
transforms.Add<TaskParameter>(new TaskParameterEntityTypeTransform());
var taskParameter = transforms.Transform<TaskParameter>(new DataRecord());
var transforms=new TransformDistributor();
添加(新任务参数EntityTypeTransform());
var taskParameter=transforms.Transform(新数据记录());
我试着理解你到底想要什么我希望这正是你想要的
您应在TaskParameter类中设置正确的参数:TaskId、名称、值
public abstract class EntityTypeTransform<TEntityType> where TEntityType : class
{
public abstract Func<IDataRecord, TEntityType> GetDataTransform();
}
public class TaskParameterEntityTypeTransform : EntityTypeTransform<TaskParameter>
{
public override Func<IDataRecord, TaskParameter> GetDataTransform()
{
return x => new TaskParameter { X = x.FieldCount };
}
}
public class TaskParameter
{
public int X { get; set; }
}
Dictionary<Type, EntityTypeTransform<TaskParameter>> imADict;
公共抽象类EntityTypeTransform,其中TEntityType:class
{
公共抽象函数GetDataTransform();
}
公共类任务ParameterEntityTypeTransform:EntityTypeTransform
{
公共覆盖函数GetDataTransform()
{
返回x=>newtaskParameter{x=x.FieldCount};
}
}
公共类任务参数
{
公共整数X{get;set;}
}
词典意象;
您可以使用
public interface IEntityTypeTransform<out TEntityType> where TEntityType : class
{
TEntityType Transform(IDataRecord dataRecord);
}
public abstract class EntityTypeTransform<TEntityType> : IEntityTypeTransform<TEntityType> where TEntityType : class
{
public abstract TEntityType Transform(IDataRecord dataRecord);
}
public class TaskParameter
{
public int TaskId;
public string Name;
public string Value;
}
public class TaskParameterEntityTypeTransform : EntityTypeTransform<TaskParameter>
{
public override TaskParameter Transform(IDataRecord dataRecord)
{
return new TaskParameter()
{
TaskId = (int)dataRecord["task_id"],
Name = (string)dataRecord["p_name"],
Value = (string)dataRecord["p_value"]
};
}
}
public class SomeClass
{
public KeyedByTypeCollection<IEntityTypeTransform<object>> TransformDictionary = new KeyedByTypeCollection<IEntityTypeTransform<object>>()
{
new TaskParameterEntityTypeTransform(),
// More transforms here
};
}
public void SomeMethod(IDataRecord dataRecord)
{
TaskParameter taskParameter = TransformDictionary.Find<TaskParameterEntityTypeTransform>().Transform(dataRecord);
}
static class TransformCache<TEntityType>
{
public static EntityTypeTransform<TEntityType> Transform { get; set; }
}
TransformCache<TaskParameter>.Transform = new TaskParameterEntityTypeTransform();