C# 带有自定义比较器的复合
我在复合C#中实现自定义比较器时遇到问题。我想将自定义比较器传递给我的复合对象 这里是IComponent接口:C# 带有自定义比较器的复合,c#,generics,C#,Generics,我在复合C#中实现自定义比较器时遇到问题。我想将自定义比较器传递给我的复合对象 这里是IComponent接口: namespace composite { public interface IComponent<T> { void Add(IComponent<T> component); IComponent<T> Find(T item); IComponent<T> Remov
namespace composite
{
public interface IComponent<T>
{
void Add(IComponent<T> component);
IComponent<T> Find(T item);
IComponent<T> Remove(T item);
string Display(int depth);
string Name { get; set; }
}
}
namespace composite
{
using System;
using System.Collections.Generic;
public class Component<T> : IComponent<T>
{
public Component(string name)
{
this.Name = name;
}
public string Display(int depth)
{
return new string('-', depth) + this.Name + "\n";
}
public string Name { get; set; }
public IComparer<T> MyComparer { get; private set; }
//public IComparer<T> myComparer { set; }
public void Add(IComponent<T> item)
{
throw new NotImplementedException();
}
public IComponent<T> Find(T item)
{
//Here I want to use comparer object, instead of Equals
//Something like this:
//return MyComparer.Compare( ... ) == 0 ? this : null;
return item.Equals(this.Name) ? this : null;
}
public IComponent<T> Remove(T item)
{
throw new NotImplementedException();
}
}
}
名称空间组合
{
公共接口IComponent
{
无效添加(IComponent组件);
i组件查找(T项);
i组件移除(T项);
字符串显示(整数深度);
字符串名称{get;set;}
}
}
对于复合对象的组件,我使用相同的接口
复合(我的组件集合)
名称空间组合
{
使用System.Collections.Generic;
使用System.Linq;
使用System.Runtime.CompilerServices;
使用系统文本;
公共类复合:IComponent
{
私有i收集组件;
私人i组件持有人;
公共组合(字符串名称)
{
this.Name=Name;
this.holder=null;
this.components=新列表();
}
公共字符串名称{get;set;}
公共无效添加(IComponent组件)
{
此.components.Add(组件);
}
公共IComponent查找(T项)
{
this.holder=this;
if(item.Equals(this.Name))
{
归还这个;
}
找到的IComponent=null;
//this.components.Select(s=>s.Name==item)
foreach(此.components中的IComponent组件)
{
查找=组件。查找(项目);
如果(找到!=null)
{
打破
}
}
发现退货;
}
公共IComponent删除(T项)
{
this.holder=this;
IComponent p=持有者。查找(项目);
if(this.holder!=null)
{
(此支架为复合材料)。部件。移除(p);
将本文件退还给持有人;
}
其他的
{
归还这个;
}
}
//公共IEnumerable Dsiplay(整数深度)
公共字符串显示(整数深度)
{
StringBuilder s=新的StringBuilder();
s、 追加(“set”+this.Name+”长度:“+this.components.Count+”\n”);
foreach(组件中的IComponent组件)
{
s、 追加(组件显示(深度+2));
}
返回s.ToString();
}
}
}
组件:
namespace composite
{
public interface IComponent<T>
{
void Add(IComponent<T> component);
IComponent<T> Find(T item);
IComponent<T> Remove(T item);
string Display(int depth);
string Name { get; set; }
}
}
namespace composite
{
using System;
using System.Collections.Generic;
public class Component<T> : IComponent<T>
{
public Component(string name)
{
this.Name = name;
}
public string Display(int depth)
{
return new string('-', depth) + this.Name + "\n";
}
public string Name { get; set; }
public IComparer<T> MyComparer { get; private set; }
//public IComparer<T> myComparer { set; }
public void Add(IComponent<T> item)
{
throw new NotImplementedException();
}
public IComponent<T> Find(T item)
{
//Here I want to use comparer object, instead of Equals
//Something like this:
//return MyComparer.Compare( ... ) == 0 ? this : null;
return item.Equals(this.Name) ? this : null;
}
public IComponent<T> Remove(T item)
{
throw new NotImplementedException();
}
}
}
名称空间组合
{
使用制度;
使用System.Collections.Generic;
公共类组件:IComponent
{
公共组件(字符串名称)
{
this.Name=Name;
}
公共字符串显示(int深度)
{
返回新字符串('-',深度)+this.Name+“\n”;
}
公共字符串名称{get;set;}
公共IComparer MyComparer{get;私有集;}
//公共IComparer myComparer{set;}
公共作废添加(IComponent项)
{
抛出新的NotImplementedException();
}
公共IComponent查找(T项)
{
//这里我想使用comparer对象,而不是Equals
//大概是这样的:
//返回MyComparer.Compare(…)==0?此值为空;
返回项.Equals(this.Name)?this:null;
}
公共IComponent删除(T项)
{
抛出新的NotImplementedException();
}
}
}
最后是我的主要功能:
namespace composite
{
class Program
{
static void Main(string[] args)
{
//Creating custom comparer and pass to the constructor composite?
IComparer<string> myComparer = new ...
IComponent<string> comp1 = new Component<string>("Komponenta 1");
IComponent<string> comp2 = new Component<string>("Komponenta 2");
IComponent<string> comp3 = new Component<string>("Komponenta 3");
IComponent<string> comp4 = new Component<string>("Komponenta 4");
IComponent<string> comp5 = new Component<string>("Komponenta 5");
IComponent<string> composite = new Composite<string>("Composite 1");
IComponent<string> composite2 = new Composite<string>("Composite 2");
composite.Add(comp1);
composite.Add(comp2);
composite.Add(comp3);
composite.Add(comp4);
composite.Add(comp5);
composite2.Add(comp1);
composite2.Add(comp2);
composite2.Add(comp3);
composite2.Add(comp4);
composite2.Add(comp5);
composite.Add(composite2);
Console.Write(composite.Display(0));
}
}
}
名称空间组合
{
班级计划
{
静态void Main(字符串[]参数)
{
//创建自定义比较器并传递到构造函数组合?
IComparer myComparer=新建。。。
IComponent comp1=新组件(“Komponta 1”);
IComponent comp2=新组件(“Komponta 2”);
IComponent comp3=新组件(“Komponta 3”);
IComponent comp4=新组件(“Komponta 4”);
IComponent comp5=新组件(“Komponta 5”);
IComponent复合材料=新复合材料(“复合材料1”);
IComponent composite2=新复合材料(“复合材料2”);
添加(comp1);
添加(comp2);
添加(comp3);
添加(comp4);
添加(comp5);
复合2.添加(复合1);
复合2.添加(复合2);
复合2.添加(复合3);
复合2.添加(复合4);
复合2.添加(复合5);
复合.添加(合成2);
Console.Write(composite.Display(0));
}
}
}
你能帮我实现自定义比较器和传递查找方法吗?
这是好办法还是不好
非常感谢这里的主要问题是:
- 组件具有
属性名称
- 组件不使用泛型类型参数
t
方法获取类型为Find
的泛型项以进行查找和比较 它带有组件名称-这仅适用于T
IComponent
- 在
中定义属性IComponent
,并 在T Data{get;set;}
和组件
组合
- 如果需要,请从
切换到IComparer
因为您希望搜索相等的组件,而不是比较元素IEqualityComparer
- 相应地更改删除方法
有什么问题吗?添加第二个argum
public class DefaultComparer<T> : IEqualityComparer<IComponent<T>>
{
public bool Equals(IComponent<T> x, IComponent<T> y)
=> EqualityComparer<T>.Default.Equals(x.Data, y.Data);
public int GetHashCode(IComponent<T> obj)
=> EqualityComparer<T>.Default.GetHashCode(obj.Data);
}
public class NameComparer<T> : IEqualityComparer<IComponent<T>>
{
public bool Equals(IComponent<T> x, IComponent<T> y)
=> string.Equals(x.Name, y.Name);
public int GetHashCode(IComponent<T> obj)
=> (obj.Name ?? string.Empty).GetHashCode();
}
var element1 = composite.Find(new Component<string>("Komponenta 5"), new NameComparer<string>());
Console.WriteLine(element1.Name);
var element2 = composite.Find(t => string.Equals(t.Name, "Komponenta 5"));
Console.WriteLine(element2.Name);